Files
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.8 KiB

3. Layered jars: the win is the second push

← 2. Measuring size · Index · Next: 4. Buildpacks →

fatjar-jre and layered-jre are the same size: 377 MB on disk, 144 MB pushed. The layers are the same bytes, cut differently.

What differs is the next build. measure-rebuild.sh changes one string constant, rebuilds every variant, and counts the layer digests that did not exist before (rebuild-delta.txt):

variant                new layers  bytes to push    image total  share
fatjar-jdk                1 of 7           23422K           178M   13.1%
fatjar-jre                1 of 7           23422K           144M   16.2%
layered-jre               1 of 11              6K           144M    0.0%
layered-alpine            1 of 10              6K            98M    0.0%
layered-distroless        1 of 39              6K            97M    0.0%
jlink-distroless          1 of 39              6K            76M    0.0%
aot-cache                 2 of 12          15323K           160M    9.6%
buildpacks                2 of 20             64K           125M    0.1%
jib                       1 of 10              2K           144M    0.0%

A fat jar re-ships all 23 MB of dependencies on every commit; a layered image ships 6 KB. Multiply by deployments per day and nodes per cluster - every node that already has revision 1 downloads only the changed layers.

Layers only help if their order matches change frequency. Put your own COPY of configuration files after the dependency layers, never before, or every change re-ships everything below it. Snapshot dependencies get their own layer because they change without a version bump.

Jib and buildpacks layer the same way without being asked.