Multi-stage Docker builds help you create smaller and faster Docker images by separating the build and runtime steps.
Multi-stage Docker builds in Spring Boot
FROM <build-image> AS build # build steps here FROM <runtime-image> COPY --from=build <source> <destination> CMD ["java", "-jar", "app.jar"]
The AS build names the first stage so you can copy files from it later.
The final stage uses a smaller image to run the app, copying only needed files.
FROM maven:3.8.6-openjdk-17 AS build WORKDIR /app COPY pom.xml . COPY src ./src RUN mvn clean package -DskipTests FROM openjdk:17-jdk-slim WORKDIR /app COPY --from=build /app/target/myapp.jar ./app.jar CMD ["java", "-jar", "app.jar"]
FROM gradle:7.5-jdk17 AS build WORKDIR /app COPY build.gradle settings.gradle ./ COPY src ./src RUN gradle build --no-daemon FROM openjdk:17-jdk-slim WORKDIR /app COPY --from=build /app/build/libs/*.jar ./app.jar CMD ["java", "-jar", "app.jar"]
This Dockerfile first builds the Spring Boot app using Maven in the build stage. Then it copies the built jar file into a smaller OpenJDK image to run the app. This keeps the final image small and clean.
FROM maven:3.8.6-openjdk-17 AS build WORKDIR /app COPY pom.xml . COPY src ./src RUN mvn clean package -DskipTests FROM openjdk:17-jdk-slim WORKDIR /app COPY --from=build /app/target/demo-0.0.1-SNAPSHOT.jar ./app.jar CMD ["java", "-jar", "app.jar"]
Always use a smaller runtime image like openjdk:17-jdk-slim for the final stage to reduce image size.
Use --from=build to copy files from the build stage by its name.
Skipping tests during build can speed up image creation but only do this if tests are run elsewhere.
Multi-stage builds separate building and running your app to keep images small.
Use a full image with build tools first, then copy only needed files to a smaller runtime image.
This method improves deployment speed, security, and image cleanliness.
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
