Discover how one Dockerfile can save you hours of build headaches and shrink your app images!
Why Multi-stage Docker builds in Spring Boot? - Purpose & Use Cases
Imagine you want to create a Docker image for your Spring Boot app. You first build the app inside the image, then copy the result to a smaller image for running. Doing this manually means writing separate Dockerfiles and copying files back and forth.
Manually managing multiple Dockerfiles or copying build artifacts is slow and error-prone. You might forget to copy files, end up with huge images full of build tools, or have inconsistent builds that are hard to debug.
Multi-stage Docker builds let you write one Dockerfile with multiple steps. You build your app in one stage, then copy only the final result to a clean, small image. This keeps images small, builds consistent, and simplifies your workflow.
FROM openjdk:17 AS builder WORKDIR /app COPY . . RUN ./gradlew build FROM openjdk:17 COPY build/libs/app.jar /app.jar CMD ["java", "-jar", "/app.jar"]
FROM openjdk:17 AS builder WORKDIR /app COPY . . RUN ./gradlew build FROM openjdk:17-jdk-slim COPY --from=builder /app/build/libs/app.jar /app.jar CMD ["java", "-jar", "/app.jar"]
It enables creating small, efficient Docker images that build reliably and run faster in production.
A developer builds a Spring Boot app with tests and dependencies in the first stage, then produces a tiny image with just the app jar and runtime for deployment to Kubernetes.
Manual Docker builds can be slow and create large images.
Multi-stage builds combine build and runtime steps in one Dockerfile.
This results in smaller images and simpler, more reliable builds.
Practice
Solution
Step 1: Understand multi-stage build purpose
Multi-stage builds separate the build environment from the runtime environment to reduce image size.Step 2: Identify benefit for Spring Boot apps
By copying only the needed files from build to runtime stage, the final image is smaller and cleaner.Final Answer:
It creates smaller and cleaner Docker images by separating build and runtime stages. -> Option AQuick Check:
Multi-stage builds = smaller images [OK]
- Confusing multi-stage builds with running multiple containers
- Thinking it updates Spring Boot version automatically
- Believing Dockerfile is not needed
Solution
Step 1: Recall Dockerfile multi-stage syntax
The correct syntax to start a build stage is 'FROM <image> AS <name>'.Step 2: Match syntax to options
Only FROM openjdk:17 AS builder uses 'FROM openjdk:17 AS builder' which is valid.Final Answer:
FROM openjdk:17 AS builder -> Option BQuick Check:
Multi-stage start = FROM ... AS ... [OK]
- Using 'STAGE' or 'BUILD' keywords incorrectly
- Placing 'AS' after the stage name
- Writing 'NEW STAGE' which is invalid
FROM maven:3.8.6-openjdk-17 AS builder WORKDIR /app COPY pom.xml . RUN mvn dependency:go-offline COPY src ./src RUN mvn package -DskipTests FROM openjdk:17-jdk-slim COPY --from=builder /app/target/myapp.jar /app/myapp.jar ENTRYPOINT ["java", "-jar", "/app/myapp.jar"]What will be the size impact of this multi-stage build compared to a single-stage build including Maven?
Solution
Step 1: Analyze multi-stage build steps
The first stage builds the app with Maven, the second stage copies only the jar file.Step 2: Understand image size impact
Since Maven and source code are not copied to the final image, it is smaller than a single-stage build including Maven.Final Answer:
The final image will be smaller because Maven and source files are excluded. -> Option AQuick Check:
Copy only jar = smaller image [OK]
- Assuming Maven stays in final image
- Thinking source files are copied to final image
- Believing multi-stage builds cause build failure here
FROM openjdk:17 AS builder WORKDIR /app COPY . . RUN ./mvnw package FROM openjdk:17-jdk-slim COPY /app/target/app.jar /app/app.jar ENTRYPOINT ["java", "-jar", "/app/app.jar"]
Solution
Step 1: Check COPY command in second stage
The COPY command uses '/app/target/app.jar' which is an absolute path on the host, not from the builder stage.Step 2: Correct COPY syntax for multi-stage
It should be 'COPY --from=builder /app/target/app.jar /app/app.jar' to copy from the builder stage.Final Answer:
The COPY command in the second stage uses an absolute path instead of a relative path from the builder stage. -> Option DQuick Check:
Use COPY --from=builder for multi-stage files [OK]
- Forgetting --from=builder in COPY
- Assuming ENTRYPOINT syntax is wrong
- Thinking WORKDIR is required in second stage
Solution
Step 1: Understand multi-stage build optimization
Building with Maven in one stage and copying only the final jar to a minimal runtime image reduces size.Step 2: Evaluate options for best practice
Use a Maven build stage to compile, then copy only the fat jar to a minimal JRE base image in the final stage. uses a build stage with Maven and a minimal JRE image for runtime, which is optimal.Final Answer:
Use a Maven build stage to compile, then copy only the fat jar to a minimal JRE base image in the final stage. -> Option CQuick Check:
Build then minimal runtime = smallest image [OK]
- Running build and runtime in one large image
- Copying unnecessary source code to final image
- Using multiple runtime stages unnecessarily
Ready to prove it?
Pass the test and this pattern moves unknown
