Skip to main content

8.3 Dockerizing Spring Boot Applications

← Back to Chapter 8: Testing, Deployment & Production-Ready Spring Boot

Packaging Spring Boot into container images requires optimizing for layer caching, minimal base image footprints, and secure non-root runtime environments.


1. The Fat JAR Inefficiency Problem​

A typical Spring Boot fat JAR contains:

  • 150 MB of dependencies that change rarely.
  • 500 KB of application business code that changes on every commit.

If you execute COPY target/*.jar app.jar, Docker invalidates the cache for the entire 150 MB layer on every build!


2. Spring Boot Layered JARs​

Spring Boot's Maven/Gradle plugins can extract JAR components into distinct physical layers:

java -Djarmode=layertools -jar application.jar extract

This produces 4 separated folders:

  1. dependencies/ (External open-source libraries)
  2. spring-boot-loader/ (Spring runtime loader)
  3. snapshot-dependencies/ (Internal team snapshots)
  4. application/ (Your application classes & resources)

3. Production Multi-Stage Dockerfile​

# Stage 1: Extraction stage
FROM eclipse-temurin:21-jre-alpine as builder
WORKDIR /workspace
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} application.jar
RUN java -Djarmode=layertools -jar application.jar extract

# Stage 2: Final Minimal Runtime
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app

# Security: Create non-root system user and group
RUN addgroup -S spring && adduser -S spring -G spring
USER spring:spring

# Copy cached layers in order of frequency of change (least frequent first!)
COPY --from=builder /workspace/dependencies/ ./
COPY --from=builder /workspace/spring-boot-loader/ ./
COPY --from=builder /workspace/snapshot-dependencies/ ./
COPY --from=builder /workspace/application/ ./

EXPOSE 8080
ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"]

Key Advantages:​

  • Lightning-Fast CI/CD Builds: Docker caches the dependencies/ layer. Re-building code pushes only the ~500 KB application layer!
  • Non-Root Security: Running as unprivileged user spring:spring prevents container escape vulnerabilities.
  • Small Attack Surface: Alpine Linux base image minimizes vulnerabilities.