In this blog, I will focus on what is available from vendor for the two application servers I am used to work with: JBoss EAP and WildFly. Along this blog, I will show few tips and concepts on docker commands.

JBoss EAP from RedHat Registry

For JBoss EAP, the best option is to get it from RedHat. To be able to pull image from RedHat registry, we must first register on registry.redhat.io. and create a service account:

Add a name and an option description and click Create. Next screen shows the generated token:

Since I will be using Docker, I select the Docker Login tab, which automatically prepares the command for me to log in to the RedHat registry:

docker login -u='*******|*****' -p=*********...******** registry.redhat.io

Expected output is Login Succeeded.

Then, we are ready to pull the image:

docker pull registry.redhat.io/jboss-eap-7/eap74-openjdk11-runtime-openshift-rhel8:7.4.10-3

This pulls JBoss EAP 7.4 with patch 10 with JDK 11 on RedHat 8:

Image Version Explained

The image version, 3 in the example above, is the version published by RedHat based on unique combination of other values. They might publish a new image for a given JDK, but not for another.

It is possible to filter existing images using docker search. For example, getting the list of all 7.4 images available on RedHat registry:

$ docker search registry.redhat.io/jboss-eap-7/eap74
NAME                                                  DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
jboss-eap-7/eap74-openjdk17-openshift-rhel8           rhcc_registry.access.redhat.com_jboss-eap-7/…   0
jboss-eap-7/eap74-openjdk8-openshift-rhel7            JBoss EAP 7.4 with OpenJDK8                     0
jboss-eap-7/eap74-openjdk11-openshift-rhel8           JBoss EAP 7.4 with OpenJDK11                    0
jboss-eap-7/eap74-openjdk17-runtime-openshift-rhel8   rhcc_registry.access.redhat.com_jboss-eap-7/…   0
jboss-eap-7/eap74-openj9-11-openshift-rhel8           JBoss EAP 7.4 with OpenJDK11 + OpenJ9           0
jboss-eap-7/eap74-openjdk11-runtime-openshift-rhel8   JBoss EAP 7.4 with OpenJDK11 (Runtime Image)    0
jboss-eap-7/eap74-openjdk8-runtime-openshift-rhel7    JBoss EAP 7.4 with OpenJDK8 (Runtime Image)     0
jboss-eap-7/eap74-openj9-11-runtime-openshift-rhel8   JBoss EAP 7.4 with OpenJDK11 + OpenJ9 (Runti…   0

WildFly on Quay.io

Quay is a container registry hosted by RedHat and could also be deployed on premises. We will pull WildFly image from Quay. As it does not require any login and will be a straightforward process:

docker pull quay.io/wildfly/wildfly:27.0.1.Final-jdk11

Comparably to JBoss EAP pull command, we can know the version we are getting:

  • 27.0.1 is WildFly version
  • jdk11 is JDK version

Running the Image

Wait, in JBoss EAP, we only pulled the image and did not run it. Let’s do it for WildFly.

docker run quay.io/wildfly/wildfly:27.0.1.Final-jdk11

Partial output:

...
09:40:51,946 INFO  [org.wildfly.extension.undertow] (MSC service thread 1-1) WFLYUT0006: Undertow HTTP listener default listening on 0.0.0.0:8080
09:40:52,327 INFO  [org.jboss.as.ejb3] (MSC service thread 1-5) WFLYEJB0493: Jakarta Enterprise Beans subsystem suspension complete
09:40:52,400 INFO  [org.wildfly.extension.undertow] (MSC service thread 1-7) WFLYUT0006: Undertow HTTPS listener https listening on 0.0.0.0:8443
09:40:52,405 INFO  [org.jboss.as.server.deployment.scanner] (MSC service thread 1-6) WFLYDS0013: Started FileSystemDeploymentService for directory /opt/jboss/wildfly/standalone/deployments
09:40:52,416 INFO  [org.jboss.as.patching] (MSC service thread 1-2) WFLYPAT0050: WildFly Full cumulative patch ID is: base, one-off patches include: none
09:40:52,498 INFO  [org.jboss.as.connector.subsystems.datasources] (MSC service thread 1-2) WFLYJCA0001: Bound data source [java:jboss/datasources/ExampleDS]
09:40:52,576 INFO  [org.jboss.ws.common.management] (MSC service thread 1-6) JBWS022052: Starting JBossWS 6.1.0.Final (Apache CXF 3.5.2.jbossorg-4)
09:40:52,757 INFO  [org.jboss.as.server] (Controller Boot Thread) WFLYSRV0212: Resuming server
09:40:52,761 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: WildFly Full 27.0.1.Final (WildFly Core 19.0.1.Final) started in 5410ms - Started 290 of 563 services (357 services are lazy, passive or on-demand) - Server configuration file in use: standalone.xml
09:40:52,764 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0060: Http management interface listening on http://127.0.0.1:9990/management
09:40:52,764 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0051: Admin console listening on http://127.0.0.1:9990

This is nice and quick, but why can’t I access this URL? If I am checking netstat -lnp output, I will not see anything binding on 9990 despite what log says. This is because I forgot to expose port outside of the container (i.e. the host), so let’s modify the command:

docker run -p 9990:9990 quay.io/wildfly/wildfly:27.0.1.Final-jdk11

Despite this change, I can’t still access the administration console. This time, it is because, by default, WildFly does not bind it to external IP of server (container in this example), thus we have to tune docker command further. Here it will not be docker specific argument, but WildFly:

docker run -p 9990:9990 quay.io/wildfly/wildfly:27.0.1.Final-jdk11 /opt/jboss/wildfly/bin/standalone.sh -b 0.0.0.0 -bmanagement 0.0.0.0

Now, we are prompted for credentials which means it is up, but I can’t find the credentials anywhere.

Building a Custom Container Image

Docker defined a file format to be able to extend an existing image. As the aim of an application server like WildFly is to run web application, additionally to setup an administrator account, we will deploy one web application. Dockerfile will look like:

FROM quay.io/wildfly/wildfly:27.0.1.Final-jdk11
RUN /opt/jboss/wildfly/bin/add-user.sh admin ********
ADD helloworld.war /opt/jboss/wildfly/standalone/deployments/
CMD ["/opt/jboss/wildfly/bin/standalone.sh", "-b", "0.0.0.0", "-bmanagement", "0.0.0.0"]

The explanation of each line:

  1. FROM: The source docker image
  2. RUN: A command run which will modify the image
  3. ADD: Copy a local file into the image
  4. CMD: Container starting command with arguments. This will make our docker command shorter.

To build the image, I am running docker build --tag=wildfly-web-app . in the directory where Dockerfile is stored (note the extra point at the end of the command):

[+] Building 1.8s (8/8) FINISHED
 => [internal] load .dockerignore                                                                                                                                                                                                      0.1s
 => => transferring context: 2B                                                                                                                                                                                                        0.0s
 => [internal] load build definition from Dockerfile                                                                                                                                                                                   0.1s
 => => transferring dockerfile: 200B                                                                                                                                                                                                   0.0s
 => [internal] load metadata for quay.io/wildfly/wildfly:27.0.1.Final-jdk11                                                                                                                                                            0.0s
 => [1/3] FROM quay.io/wildfly/wildfly:27.0.1.Final-jdk11                                                                                                                                                                              0.1s
 => [internal] load build context                                                                                                                                                                                                      0.1s
 => => transferring context: 74.39kB                                                                                                                                                                                                   0.0s
 => [2/3] RUN /opt/jboss/wildfly/bin/add-user.sh admin admin                                                                                                                                                                           1.4s
 => [3/3] ADD helloworld.war /opt/jboss/wildfly/standalone/deployments/                                                                                                                                                                0.1s
 => exporting to image                                                                                                                                                                                                                 0.1s
 => => exporting layers                                                                                                                                                                                                                0.1s
 => => writing image sha256:e3d58dc0ebe2554ce7f9e5e7da2a5483c7e7c6801159ec05a45c5d66577c46d9                                                                                                                                           0.0s
 => => naming to docker.io/library/wildfly-web-app

Now, I have a new docker image available:

REPOSITORY                        TAG                  IMAGE ID       CREATED          SIZE
wildfly-web-app                   latest               e3d58dc0ebe2   33 seconds ago   848MB

Let’s run it with an additional exposed port for the web app:

docker run -p 9990:9990 -p 8080:8080 wildfly-web-app

It is up and ready:

With a deployed web application:

helloworld deployment

My Opinion

Even if these pre-built images are nice, we must extend them in a way or another, thus I prefer to use YaK to deploy and configure ready to use servers with our best practices already embedded.