Using JLink to Create Smaller JRE Docker Images

JLink is a tool included with the JDK (Java Development Kit) starting from Java 9 that lets you create a custom, minimal Java runtime containing only the modules your application actually needs.

Instead of using the full 200+ MB JDK/JRE, you can use JLink to generate a slim, app-specific JRE image.

Create a smaller JRE Docker image for Spring Boot Application

1. Build the Spring Boot application with Gradle

$ ./gradlew bootJar

2. Dockerfile

FROM eclipse-temurin:21-alpine AS jre-build
WORKDIR /app
COPY build/libs/myapp.jar myapp.jar
# Unpack the JAR file
RUN jar -xvf myapp.jar
# Get the modules needed for the Spring Boot application
RUN jdeps --ignore-missing-deps -q \
--recursive \
--multi-release 21 \
--print-module-deps \
--class-path 'BOOT-INF/lib/*' \
myapp.jar > deps.info
RUN cat deps.info
# Create a custom Java runtime
RUN $JAVA_HOME/bin/jlink \
--add-modules $(cat deps.info) \
--strip-debug \
--no-man-pages \
--no-header-files \
--compress=2 \
--output /javaruntime

# Define your base image
FROM alpine:3 AS runtime
ENV JAVA_HOME=/opt/java/openjdk
ENV PATH="${JAVA_HOME}/bin:${PATH}"
COPY --from=jre-build /javaruntime $JAVA_HOME
# Copy the application JAR file
WORKDIR /app
COPY build/libs/myapp.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]

3. Build Docker image

docker build -t myapp . 

After use the smaller JRE Docker images that JLink created, the image size of the Spring Boot application has decreased from 227MB to 90MB.

4. Running Docker container

docker run --name myapp -p 8080:8080 myapp

5. Access the application

Visiting http://localhost:8080/

Create a smaller JRE to run the Spring Boot application JAR file

1. Build the Spring Boot application with Gradle

$ ./gradlew bootJar

2. Create a smaller JRE

$ mkdir my-workspace && cd my-workspace
$ cp ../build/libs/myapp.jar .
# Unpack the JAR file
$ jar -xvf myapp.jar
# Get the modules needed for the Spring Boot application
$ jdeps --ignore-missing-deps -q \
--recursive \
--multi-release 21 \
--print-module-deps \
--class-path 'BOOT-INF/lib/*' \
myapp.jar > deps.info
$ cat deps.info
# Create a custom Java runtime
$ jlink \
--add-modules $(cat deps.info) \
--strip-debug \
--no-man-pages \
--no-header-files \
--compress=2 \
--output ./my-custom-jre

3. Using the smaller JRE to run Spring Boot application JAR file

$ ./my-custom-jre/bin/java -jar myapp.jar

4. Access the application

Visiting http://localhost:8080/