Layered Docker images for Spring Boot
Copying a fat jar into an image puts 80 MB of dependencies and 200 KB of our own code into one layer. Every commit then uploads everything again. Spring Boot can extract the jar into layers ordered by how often they change.
FROM eclipse-temurin:21-jre AS builder
WORKDIR /builder
COPY target/*.jar application.jar
RUN java -Djarmode=tools -jar application.jar extract --layers --destination extracted
FROM eclipse-temurin:21-jre
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"]
Dependencies go first and stay cached in the registry; the application layer goes last. After the first push, a typical build uploads only that last layer.
The tools jar mode needs Spring Boot 3.3 or newer. Older versions use -Djarmode=layertools with a slightly different layout.