Dockerizing Java MicroProfile Applications

For cloud-native applications Kubernetes and Istio deliver a lot of important functionality out of the box, for example to ensure resiliency and scalability. This functionality works generically for microservices, no matter in which language they have been implemented and independent from the application logic.

Some cloud-native functionality however cannot be handled by Kubernetes and Istio, since it needs to be handled in the business logic of the microservices, for example application specific failover functionality, metrics and fine-grained authorization.

MicroProfile

That’s why I started to look into Eclipse MicroProfile which is an extension to JavaEE to build microservices-based architectures and a great programming model for Istio. In addition to the application specific logic that Istio cannot handle, it also comes with convenience functionality that you typically need when developing microservices, for example invoking REST APIs and implementing REST APIs including their documentation.

There is a MicroProfile Starter that includes several simple samples for MicroProfile functionality. In order to try these features in Istio, I’ve started to create a simple sample application.

Get the code of the cloud-native starter sample.

Container

The first thing you need to run MicroProfile applications on Kubernetes is an image. MicroProfile is supported by several Java application servers, different JVMs can be used and there are different versions of all of these components. Because of this there are many different images you need to choose from.

I looked for an image that contains only components that are available as open source. Here is my Open Liberty server.xml file and this is how my Dockerfile looks like:

FROM openliberty/open-liberty:microProfile2-java8-openj9
ADD https://github.com/WASdev/sample.opentracing.zipkintracer/releases/download/1.2/liberty-opentracing-zipkintracer-1.2-sample.zip /
RUN unzip liberty-opentracing-zipkintracer-1.2-sample.zip -d /opt/ol/wlp/usr/ \
 && rm liberty-opentracing-zipkintracer-1.2-sample.zip
COPY liberty/server.xml /config/
ADD target/articles.war /config/dropins/

The image contains these components:

There are several different images available for Open Liberty. I picked a community image since it comes with OpenJ9 instead of the IBM version of OpenJ9. Unfortunately that image doesn’t seem to support MicroProfile 2.2 yet (at least I haven’t found it).

Additionally I download and copy a file needed for Zipkin tracing onto the image which you need to do manually at this point if you want to use the tracing functionality built into MicroProfile. This functionality is pretty useful since it allows you to see the chains of invocations between microservices.

This screenshot shows the Jaeger dashboard. The BFF (backend for frontend) ‘web-api’ microservice invokes another ‘articles’ service:

jaeger-starter

Variations of the Dockerfile

In order to avoid downloading the Zipkin file every time a new image is built, I’ve created a slightly different Dockerfile where the file is added from a local directory. The image is built with a script that downloads the file if it doesn’t exist locally. Alternatively you can download the file via Maven (check out the example pom.xml and example Dockerfile).

Additionally I have created another variation of the Docker image so that my sample application can be installed even by people who don’t have Java and Maven installed locally (or who have wrong Java/Maven versions). This Dockerfile uses a multistage build.

FROM maven:3.5-jdk-8 as BUILD
COPY src /usr/src/app/src
COPY pom.xml /usr/src/app
RUN mvn -f /usr/src/app/pom.xml clean package

FROM openliberty/open-liberty:microProfile2-java8-openj9
ADD liberty-opentracing-zipkintracer-1.2-sample.zip /
RUN unzip liberty-opentracing-zipkintracer-1.2-sample.zip -d /opt/ol/wlp/usr/ \
 && rm liberty-opentracing-zipkintracer-1.2-sample.zip
COPY liberty/server.xml /config/
COPY --from=BUILD /usr/src/app/target/articles.war /config/dropins/

Sample Application

If you want to try MicroProfile on Istio, use the sample application, set up a local development environment, make sure you have installed all necessary prerequisites and run these commands:

$ git clone https://github.com/nheidloff/cloud-native-starter.git
$ scripts/check-prerequisites.sh
$ scripts/deploy-articles-java-jee.sh
$ scripts/deploy-web-api-java-jee.sh

Leave a Reply