WildFly Java Microservice - PART 1: Docker Image
In this guide, you will learn how to create and run a Docker Image containing a Jakarta REST service implemented using WildFly.
Prerequisites
Maven Project
Create a simple Jakarta EE application Maven Project containing a Jakarta REST service using the org.wildfly.archetype:wildfly-getting-started-archetype
archetype:
mvn archetype:generate \
-DarchetypeGroupId=org.wildfly.archetype \
-DarchetypeArtifactId=wildfly-getting-started-archetype
Note
|
See Getting Started with WildFly for the details |
pom.xml
We need to add some features that will be required when, in the next guide, we will run our application on Kubernetes; specifically, we need to expose Liveness, Readiness and Startup Probes; we can add these features thanks to the wildfly-cloud-galleon-pack.
Update the pom.xml
file and add the wildfly-cloud-galleon-pack to the wildfly-maven-plugin configuration like in the following:
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>5.0.0.Final</version>
<configuration>
<feature-packs>
<feature-pack>
<location>org.wildfly:wildfly-galleon-pack:32.0.0.Final</location>
</feature-pack>
<feature-pack>
<location>org.wildfly.cloud:wildfly-cloud-galleon-pack:7.0.0.Final</location>
</feature-pack>
</feature-packs>
<layers>
<layer>cloud-server</layer>
</layers>
</configuration>
<executions>
<execution>
<goals>
<goal>package</goal>
</goals>
</execution>
</executions>
</plugin>
Build the application
$ mvn clean package
...
[INFO] Copy deployment /home/tborgato/Documents/WildFly-Mini-Serie/getting-started/target/ROOT.war to /home/tborgato/Documents/WildFly-Mini-Serie/getting-started/target/server/standalone/deployments/ROOT.war
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.478 s
[INFO] Finished at: 2024-04-12T17:35:46+02:00
[INFO] ------------------------------------------------------------------------
Start the application
$ ./target/server/bin/standalone.sh
...
17:36:25,755 INFO [org.wildfly.extension.undertow] (MSC service thread 1-3) WFLYUT0006: Undertow HTTP listener default listening on 0.0.0.0:8080
...
17:36:25,967 INFO [org.jboss.weld.deployer] (MSC service thread 1-2) WFLYWELD0003: Processing weld deployment ROOT.war
...
17:36:26,835 INFO [org.jboss.resteasy.resteasy_jaxrs.i18n] (ServerService Thread Pool -- 62) RESTEASY002225: Deploying jakarta.ws.rs.core.Application: class org.wildfly.examples.GettingStartedApplication
17:36:26,859 INFO [org.wildfly.extension.undertow] (ServerService Thread Pool -- 62) WFLYUT0021: Registered web context: '/' for server 'default-server'
17:36:26,883 INFO [org.jboss.as.server] (ServerService Thread Pool -- 35) WFLYSRV0010: Deployed "ROOT.war" (runtime-name : "ROOT.war")
17:36:26,901 INFO [org.jboss.as.server] (Controller Boot Thread) WFLYSRV0212: Resuming server
17:36:26,904 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0060: Http management interface listening on http://127.0.0.1:9990/management
17:36:26,904 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0054: Admin console is not enabled
17:36:26,904 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: WildFly Full 31.0.0.Final (WildFly Core 23.0.1.Final) started in 2175ms - Started 280 of 378 services (149 services are lazy, passive or on-demand) - Server configuration file in use: standalone.xml
As you can see, the application started, and it’s ready to serve requests on port 8080
.
Check the application
Go to this URL:
either in your browser or using a utility like curl
:
$ curl http://127.0.0.1:8080/hello/pippo
Hello 'pippo'.
Check Liveness, Readiness and Startup Probes
Go to these URLs:
either in your browser, or using a utility like curl
:
$ curl http://127.0.0.1:9990/health/live
{"status":"UP","checks":[{"name":"empty-liveness-checks","status":"UP"}]}
$ curl http://127.0.0.1:9990/health/ready
{"status":"UP","checks":[{"name":"suspend-state","status":"UP","data":{"value":"RUNNING"}},{"name":"server-state","status":"UP","data":{"value":"running"}},{"name":"deployments-status","status":"UP","data":{"ROOT.war":"OK"}},{"name":"boot-errors","status":"UP"},{"name":"ready-deployment.ROOT.war","status":"UP"}]}
$ curl http://127.0.0.1:9990/health/started
{"status":"UP","checks":[{"name":"started-deployment.ROOT.war","status":"UP"}]}
Everything works fine!
Let’s move on and package our application in a Docker Image …
Docker Image
Dockerfile
We will use the Dockerfile from examples/docker-build/Dockerfile because it is crafted specifically for WildFly.
Create a file named Dockerfile
in the same directory as the pom.xml
file, with the following content:
ARG runtime_image=quay.io/wildfly/wildfly-runtime:latest
FROM ${runtime_image}
COPY --chown=jboss:root target/server $JBOSS_HOME
RUN chmod -R ug+rwX $JBOSS_HOME
Build the Docker Image
Build the Docker Image my-jaxrs-app:latest
with the following command:
$ podman build -t my-jaxrs-app:latest .
STEP 1/3: FROM quay.io/wildfly/wildfly-runtime:latest
STEP 2/3: COPY --chown=jboss:root target/server $JBOSS_HOME
-→ cf1b99511a9b
STEP 3/3: RUN chmod -R ug+rwX $JBOSS_HOME
COMMIT my-jaxrs-app:latest
-→ e1ab6e80ed20
Successfully tagged localhost/my-jaxrs-app:latest
e1ab6e80ed20c3619a7e859f03c71f33b79a4d292f971ed83e7484f4779121d8
Run the Docker Image
To check that our brand-new my-jaxrs-app:latest
Docker Image works as expected, run the following command:
$ podman run --rm -p 8080:8080 -p 9990:9990 \
--name=my-jaxrs-app \
my-jaxrs-app
…
16:14:49,477 INFO [org.wildfly.extension.undertow] (MSC service thread 1-5) WFLYUT0006: Undertow HTTP listener default listening on 0.0.0.0:8080
…
16:14:49,677 INFO [org.jboss.weld.deployer] (MSC service thread 1-4) WFLYWELD0003: Processing weld deployment ROOT.war
…
16:14:50,403 INFO [org.jboss.resteasy.resteasy_jaxrs.i18n] (ServerService Thread Pool — 61) RESTEASY002225: Deploying jakarta.ws.rs.core.Application: class org.wildfly.examples.GettingStartedApplication
16:14:50,426 INFO [org.wildfly.extension.undertow] (ServerService Thread Pool — 61) WFLYUT0021: Registered web context: '/' for server 'default-server'
16:14:50,451 INFO [org.jboss.as.server] (ServerService Thread Pool — 35) WFLYSRV0010: Deployed "ROOT.war" (runtime-name : "ROOT.war")
16:14:50,459 INFO [org.jboss.as.server] (Controller Boot Thread) WFLYSRV0212: Resuming server
16:14:50,460 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0060: Http management interface listening on http://0.0.0.0:9990/management
16:14:50,460 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0054: Admin console is not enabled
16:14:50,461 INFO [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: WildFly Full 31.0.0.Final (WildFly Core 23.0.1.Final) started in 1101ms - Started 280 of 378 services (149 services are lazy, passive or on-demand) - Server configuration file in use: standalone.xml
As you can see, the application started, and it’s ready to serve requests on port 8080
.
Note
|
we explicitly mapped port 8080 in the container to port 8080 on the HOST (your PC); we also mapped port 9990 in the container to port 9990 on the HOST to expose the Liveness, Readiness and Startup Probes.
|
Check the application
Repeat the checks in Check the application.
Note
|
the only difference here, is that the response is served by the application running inside our my-jaxrs-app:latest Docker Image
|
Check Liveness, Readiness and Startup Probes
Repeat the checks in Check Liveness, Readiness and Startup Probes;
Note
|
here too, the only difference, is that the responses are served by the application running inside our my-jaxrs-app:latest Docker Image
|
Stop the Docker container
Stop the running container:
$ podman stop my-jaxrs-app