VisualVM & Wildfly running in Docker

In Imixs-Workflow project we use mostly use Wildfly Server to run the Imixs-Worklfow engine. If you want to profile your workflow instance in details you can use the VisualVM profiling tool. To use this tool when running Wildfly in a container will be the topic of this blog post. You can download VisualVM form Github.

When running Wildfly in a container you need to use the remote profile capabilities of VIsualVM to analyse your services. There for your wildfly server running in a docker container should publish the port 9990 which is also the port for the Wildfly Web Interface. Using the Imixs Wildfly Docker image you can simply launch your server with the option “DEBUG=true”.

Next you need to download the wildfly version running in your container into your local workstation as you need some libraries only contained in the corresponding wildfly version. Go to the Wildfly Download page to download the version your are running in your container.

Lets assume you have extracted the wildfly server packages into the following directory

$ /opt/wildfly-18.0.0.Final

than you can start VisualVM with the following option:

$ ./visualvm -cp:a /opt/wildfly-18.0.0.Final/bin/client/jboss-cli-client.jar  -J-Dmodule.path=/opt/wildfly-18.0.0.Final/modules	

Take note of the correct server path.

Now you can connect to your wildfly server with a new JMX Connection which you can open from the ‘file’ menu in VisualVM

To connec to to use the following URL:


Note that you may need a admin user account on your wildfly server. If you are unsure open your wildfly web console first form a web browser:

OpenLiberty – Performance

In the course of our open source project Imixs-Office-Workflow, I have now examined OpenLiberty in more detail. And I came up to the conclusion that OpenLiberty has a very impressive performance.


I run OpenLiberty in Docker in the version ‘’. Our application is a full featured Workflow Management Suite with a Web Interface and also a Rest API. So for OpenLiberty we use the following feature set:


As recommended by OpenLiberty I use the following Dockerfile layout:

FROM openliberty/open-liberty:
# Copy postgres JDBC driver
COPY ./postgresql-9.4.1212.jar /opt/ol/wlp/lib
# Add config
COPY --chown=1001:0 ./server.xml /config/server.xml

# Activate Debug Mode...
# COPY --chown=1001:0 ./jvm.options /config/

# Copy sample application
COPY ./imixs-office-workflow*.war /config/dropins/


The important part here is the RUN command at the end of the Dockerfile. This script adds the requested XML snippets and grow image to be fit-for-purpose. This makes the docker build process a little bit slower, but the startup of the image is very fast.

I measured a startup time of round about 12 seconds. This is very fast for the size and complexity of this application. And it is a little bit faster than the startup of Wildfly with round about 15 seconds. Only in case of a hot-redeploy of the application Wildfly seems to be a little bit faster (6 seconds) in compare to OpenLiberty (8 seconds).

Open LibertyWildfly
Docker Startup Time12 sec15 sec
Application Hot Deploy8 sec6 sec

Debug Mode

Note: activating the debug port makes OpenLiberty performance very poor. So do not forget to deactivate debugging in productive mode! The debug mode can be activated by providing a jvm.options file like this:


I have commented on this in the Dockerfile example above.

Payara Micro with Custom Configuration

This is a short guideline how to create a payara-micro Docker container with a custom configuration. A custom configuration is needed if you want to configure application server resources like database pools, mail resources or other stuff needed by your application.

1) Downlaod the payara-micro.jar

First you need to download the payara-mciro jar. Go the the official payara download page:

2) Copy the domain.xml

Next you can inspect the jar file and copy the domain.xml from the config directory


Now you can customize the domain.xml as needed by your project. The configuration is identically to payara-full so you can add all additional resources and configuration. For example you can add a custom data pool configuration into the resources section of the domain.xml.

3) Create a Dockerfile

Now you can create your custom Dockerfile. Payara-micro can be configured with launch options in several ways. One of them allows you to define a custom location of your configuration and domain.xml files. See the following example:

FROM payara/micro
USER root
# create a custom config folder
RUN mkdir ${PAYARA_HOME}/config
COPY domain.xml ${PAYARA_HOME}/config/
COPY postgresql-42.2.5.jar ${PAYARA_HOME}/config
RUN chown -R payara:payara ${PAYARA_HOME}/config
USER payara
# Deploy artefacts
COPY my-app.war $DEPLOY_DIR
CMD ["--addLibs","/opt/payara/config/postgresql-42.2.5.jar", "--deploymentDir", "/opt/payara/deployments", "--rootDir", "/opt/payara/config","--domainConfig", "/opt/payara/config/domain.xml"]]

In this Dockerfile derived from the official payra/micro I create a new config/ folder to copy the jdbc-driver and the domain.xml.

The CMD option is important here. I added the following custom settings:

  • –addLibs – adds the postgresql jdbc driver
  • –deploymentDir – set the default deployment directory
  • –rootDir set the configuration directory to our new /opt/payara/config/ folder
  • –domainConfig – define the location of the custom domain.xml

With the CMD option –rootDir you can specify what directory Payara Micro should use as its new domain directory. Adding files to this directory will replicate the behavior of a Payara Server’s domain configuration. Payara-Micro automatically copies the folder with configuration files we do not specified explicitly. So at the end the folder contains all necessary configuation.

The CMD option –domainConfig is necessary. Otherwise payara-micro will ignore your custom domain.xml . More information which options can be added can be found here.

4) Build and Launch your Custom Docker Image

Finally you can now build your custom Docker image…

$ docker build --tag=my-custom-payara-micro .

…and start your docker container:

$ docker build --tag=my-custom-payara-micro .

Now you launched (hopefully without errors your custom payara-micro). I hope this helps you to get started with payara-micro and docker.