In my last adventure into the realm of Spring Boot and Docker, we explored the art of creating compact images using a JRE base. The journey was enlightening, but the quest for minimalism in Docker images never truly ends. So, let's embark on a new escapade, this time armed with the mighty jlink command.
Why jlink?
We love our Java applications, but we're not fans of oversized Docker images. jlink
steps in to shrink the footprint by creating a runtime that contains only the modules required for our app. Smaller images mean faster downloads, quicker startups, and happier users.
Before we can use jlink
, we need to determine which JDK modules are required by the application. We need Jdeps
, a Java dependency analysis tool to list all the module dependencies.
To know more about how to use jdeps
with the Spring Boot project you can look at this article.
Run JLink to create a custom Java Runtime
We added the jlink
execution at the build stage. Later in the final stage, will copy the output into the final image.
RUN jlink -v \
--add-modules java.base,java.logging,java.xml,jdk.unsupported,java.sql,java.naming,java.desktop,java.management,java.security.jgss,java.instrument \
--strip-debug \
--compress 2 \
--no-header-files \
--no-man-pages \
--vendor-version="i made this" \
--output /customjre
Arguments:
add-modules
Adds the modules, to the default set of root modules. The module's name was generated byjdeps
.strip-debug
will remove debugging information from the output runtime image.compress=0|1|2
Enable compression of resources: 0= no compression, 1= string deduplication, 2= zip-compressed. This might influence startup time slightly.vendor-version="I made this"
will appear on the second line of the output ofjava -version
no-header-files
Excludes header files.no-man-pages
Excludes man pages.output
Specifies the location of the generated runtime image.
After creating the custom JRE, we copy it into the JAVA_HOME of the final stage. The full dockerfile can be found here.
FROM alpine:3.18.4
ENV JAVA_HOME /user/java/jdk21
ENV PATH ${JAVA_HOME}/bin:$PATH
COPY --from=java-build /customjre ${JAVA_HOME}
After rebuilding the docker image, here is the final result:
We reduced the image size from 232MB to 98 MB. Finally, we have a smaller docker image of the Spring Boot application using Alpine Linux and Open JDK21.
Top comments (0)