Files
spring-boot-demo/docker-images/docs/01-the-variants.md
T
asmhatreandClaude Opus 5 644da9e65e Add docker-images: one Spring Boot 4 service packaged nine ways
Companion code for "Dockerizing Spring Boot 4: Layered Jars, Buildpacks,
Distroless and Image Size Benchmarks". Fat jar on JDK and JRE, layered jar
on Debian, Alpine and distroless, jlink, the JDK 25 AOT cache, Paketo
buildpacks and Jib, each measured for size on disk and pushed, rebuild
delta, startup, user and shell. Also PID 1 and signal handling, the jdeps
module gap, AOT cache mismatches and buildpacks memory calculation.
Transcripts in docs/output/, regenerated by scripts/run-all.sh.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01C3TETMrqVUWeFkNtz3Jbo3
2026-09-11 17:11:46 +00:00

1.9 KiB

1. The variants and how each is built

Index · Next: 2. Measuring size →

All nine start from the same target/app.jar (25 MB). The Dockerfiles are in docker/, each with a comment saying what it is for.

The layered pattern

FROM eclipse-temurin:25-jre AS builder
WORKDIR /builder
COPY target/app.jar application.jar
RUN java -Djarmode=tools -jar application.jar extract --layers --destination extracted

FROM gcr.io/distroless/java25-debian13:nonroot
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 ["java", "-jar", "application.jar"]

extract without --launcher writes a thin application.jar whose manifest Class-Path lists lib/*.jar, so the runtime stage launches with plain java -jar - no JarLauncher, no nested-jar class loading. list-layers on this jar prints dependencies, spring-boot-loader, snapshot-dependencies, application, in that order: least likely to change first.

The builder stage uses the Temurin JRE, not the JDK: extract needs only a JVM. Only the jlink variant needs the JDK, for jdeps and jlink.

Buildpacks and Jib in a restricted network

The committed output was produced in a sandbox with no route to Docker Hub or Maven Central. The flags that made that work are in run-all.sh:

  • Buildpacks: -Pcorporate-proxy,no-maven-central -Dspring-boot.build-image.pullPolicy=IF_NOT_PRESENT (chapter 4)
  • Jib: -Djib.from.image=docker://eclipse-temurin:25-jre - take the base image from the local daemon

With ordinary internet access, mvn spring-boot:build-image and mvn jib:dockerBuild need no flags.