# 6. A custom runtime: jdeps works out which JDK modules the application needs, jlink builds a # JRE containing only those, and it goes onto distroless java-base (glibc, no JRE of its own). # See docs/05-jlink.md for the module list this produced and the one it initially missed. FROM eclipse-temurin:25-jdk AS builder WORKDIR /builder COPY target/app.jar application.jar RUN java -Djarmode=tools -jar application.jar extract --layers --destination extracted # jdeps cannot see modules loaded reflectively. jdk.management is the one this application # needs: without it Micrometer silently drops 15 metrics, GC pauses and CPU usage among them. ARG EXTRA_MODULES="jdk.management" RUN MODULES="$(jdeps --ignore-missing-deps -q --recursive --multi-release 25 --print-module-deps \ --class-path 'extracted/dependencies/lib/*' extracted/application/application.jar)" \ && MODULES="${MODULES}${EXTRA_MODULES:+,$EXTRA_MODULES}" \ && echo "jlink modules: $MODULES" | tee /builder/modules.txt \ && jlink --add-modules "$MODULES" --strip-debug --no-man-pages --no-header-files \ --compress=zip-6 --output /builder/jre FROM gcr.io/distroless/java-base-debian13:nonroot COPY --from=builder /builder/jre /opt/jre COPY --from=builder /builder/modules.txt /opt/jre/modules.txt WORKDIR /application COPY --from=builder /builder/extracted/dependencies/ ./ COPY --from=builder /builder/extracted/spring-boot-loader/ ./ COPY --from=builder /builder/extracted/snapshot-dependencies/ ./ COPY --from=builder /builder/extracted/application/ ./ ENTRYPOINT ["/opt/jre/bin/java", "-jar", "application.jar"]