Java Apps From Source to Image with Docker
When you have a Java app, you may want to create a Docker image for it and deploy to Kubernetes. There are two steps here:
- Build Java source code and package as a JAR file.
- Build a Docker image from the JAR file with JDK.
With a normal build process, these two steps are separated. The first step is done with Maven/Gradle on the local machine. The second step is done by creating an image from Dockerfile
using local files generated in the first step. This may not be possible when using continuous integration provided by public container registries like Docker Hub or Quay.io. This is because these registries only support building Docker images.
With the help of Docker's multi-stage builds, we can easily combine these two steps into one.
Given a Spring Boot app, the Dockerfile
below can be used to build images from source code. The first stage uses the Maven image as the base. After copying src
directory and pom.xml
file to the image, Maven is used to build the Java source code. builder
is the name of this stage. After the build, the /build/target
directory contains the JAR file.
The second stage uses OpenJDK 11 Alpine image as the base image, the COPY
command copies the JAR file built in the first stage to the current image. The option --from=builder
specifies the source of copy action.
FROM maven:3.6.3-openjdk-11 AS builder
RUN mkdir /build
ADD src /build/src
ADD pom.xml /build
RUN cd /build && mvn -B -ntp package
FROM adoptopenjdk/openjdk11:alpine-jre
COPY /build/target/docker-build-test-0.0.1-SNAPSHOT.jar /app.jar
CMD ["java", "-jar", "/app.jar"]
When this Dockerfile
is built, the result image contains only the JDK and JAR file.