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 --from=builder /build/target/docker-build-test-0.0.1-SNAPSHOT.jar /app.jar CMD ["java", "-jar", "/app.jar"]
Dockerfile is built, the result image contains only the JDK and JAR file.