HOWTO: Containerize a Natively Compiled Java Application Using Docker
Notice Information in this article applies to Excelsior JET version 11.0 and above.
APPLICABILITY
This article was written when Docker Engine was at version 1.11 and may not fully apply to other versions.
WARNING: As of 13-Feb-2017, it only works for the 64-bit version of Excelsior JET due to Docker bug #28162.
SUMMARY
Docker is a popular software containerization platform, often used to deploy microservices.
This article provides instructions for deploying natively compiled Java applications with Docker.
PREREQUISITES
This article assumes that you already have a Maven or Gradle project configured for a native build using the respective Excelsior JET plugin.
DETAILS
To enable containerization of your natively compiled Java application, you need to add two files to the root dicrectory of your project, Dockerfile
and .dockerignore
. Their contents will differ slightly depending on whether you are using Maven or Gradle.
Dockerfile
The Dockerfile
should contain at least the following two instructions:
FROM <base-image>
COPY <host-app-location> <target-app-location>
. . .
The FROM
instruction goes first in a Dockerfile. It sets the base image for subsequent instructions. Java Applications compiled with Excelsior JET require glibc, so pick a <base-image>
that includes glibc, for instance:
FROM frolvlad/alpine-glibc:alpine-3.4
The COPY
instruction copies your natively compiled Java application from a <host-app-location>
in the context of the build to the filesystem of the container at the desired <target-app-location>
, such as /app
.
Depending on your build tool, <host-app-location>
should equal:
Maven: target/jet/app
Gradle: build/jet/app
Further Dockerfile instructions may define the command to run your application, network ports on which the container will listen at run time, and so on.
For instance, here is a minimalistic Dockerfile for a Tomcat Web application built with Maven:
FROM frolvlad/alpine-glibc:alpine-3.4
COPY target/jet/app /app
ENTRYPOINT ["/app/bin/catalina.sh", "run"]
EXPOSE 8080
and another one for the same application built with Gradle:
FROM frolvlad/alpine-glibc:alpine-3.4
COPY build/jet/app /app
ENTRYPOINT ["/app/bin/catalina.sh", "run"]
EXPOSE 8080
.dockerignore
The .dockerignore
file tells the Docker Engine which files it should not include in the container image. Use it to exlude large, irrelevant and sensitive files, such as application source code, files and directories pertaining to your version control system, and so on.
If you are using Maven:
src/* target/* !target/jet/app pom.xml .git .gitignore
If you are using Gradle:
.gradle build/* gradle src/* !build/jet/app build.gradle gradlew gradlew.build .git .gitignore
Important: If you are using a version control system other than Git, make sure to replace the last two lines of .dockerignore
with patterns to exclude the respective files and directories, e.g. .svn
.
Building Images and Launching Containers
Make sure that you have successfully built the latest version of your application:
# If using Maven: mvn jet:build
# If using Gradle: gradlew jetBuild
Build a Docker image:
docker build <options> .
This should print
Successfully built <image>
Create and start a container based on that image:
docker run <options> <image>
Use <options>
to tag the image for easy reference, publish network ports and so on. Refer to the official Docker documentation for details.
To continue the previous example, the following commands will containerize a Tomcat Web application, run it, and remove the container upon termination:
docker build -t my-app .
docker run -p 8080:8080 --rm -ti my-app
REFERENCES
- Excelsior JET Maven plugin
- Excelsior JET Gradle plugin
- Docker
- HOWTO: Natively Compile a Spring Boot Application
Article ID: 39
Last Revised On: 22-Jul-2016