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
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
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:
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.1is WildFly version
jdk11is 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
... 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:
- FROM: The source docker image
- RUN: A command run which will modify the image
- ADD: Copy a local file into the image
- 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:
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.