What is Multi-Stage Docker Build?
A Multi-Stage Docker Build is a Dockerfile optimization technique where multiple build stages are used inside a single Dockerfile to create smaller, cleaner, secure, and production-ready Docker Images.
In modern DevOps, Kubernetes, microservices, CI/CD pipelines, and cloud-native systems, multi-stage builds are considered one of the most important Docker best practices.
Why Multi-Stage Builds are Important
Traditional Docker builds often create very large images because they include:
- Build tools
- Source code
- Maven cache
- Node modules
- Temporary files
- Testing tools
These unnecessary files increase:
- Image size
- Security vulnerabilities
- Deployment time
- Storage usage
- Network transfer time
Multi-stage builds solve these problems by creating separate stages for building and running the application.
“Build in one stage, run in another lightweight stage.”
Real-Time Analogy
Think of building a house.
Construction Phase:
- Cement
- Machines
- Tools
- Workers
Final House:
- Clean house only
- Construction tools removed
Similarly:
Build Stage:
- Maven
- JDK
- Source code
- Build tools
Runtime Stage:
- Only JAR file
- Lightweight JRE
Without Multi-Stage Build
FROM maven:3.9.6-eclipse-temurin-17
WORKDIR /app
COPY . .
RUN mvn clean package
EXPOSE 8080
CMD ["java", "-jar", "target/app.jar"]
Problems
- Large image size
- Contains Maven and source code
- Higher security risk
- Slow deployments
- Wasted storage
With Multi-Stage Build
FROM maven:3.9.6-eclipse-temurin-17 AS build
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline -B
COPY src ./src
RUN mvn clean package -DskipTests
FROM eclipse-temurin:17-jre-jammy
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
Benefits
- Smaller image size
- Faster deployments
- Improved security
- Cleaner runtime image
- Better production performance
How Multi-Stage Docker Build Works Internally
Stage 1:
Build Application
|
v
Generate JAR File
|
v
Stage 2:
Copy Only Required Files
|
v
Create Lightweight Runtime Image
Multi-Stage Build Architecture
+------------------------------------------------------+
| Build Stage |
|------------------------------------------------------|
| Maven |
| JDK |
| Source Code |
| Dependencies |
| Build Tools |
+------------------------------------------------------+
|
v
+------------------------------------------------------+
| Runtime Stage |
|------------------------------------------------------|
| Lightweight JRE |
| Application JAR |
| Runtime Configurations |
+------------------------------------------------------+
|
v
+------------------------------------------------------+
| Production Container |
+------------------------------------------------------+
Understanding the Build Stage
Example
FROM maven:3.9.6-eclipse-temurin-17 AS build
This stage:
- Uses Maven image
- Contains JDK
- Compiles source code
- Builds application JAR
Why Named "build"?
The keyword:
AS build
gives a name to the stage so later stages can copy files from it.
Understanding Runtime Stage
FROM eclipse-temurin:17-jre-jammy
This stage:
- Uses lightweight JRE
- Does not include Maven
- Does not include source code
- Contains only runtime files
Understanding COPY --from
COPY --from=build /app/target/*.jar app.jar
This copies the JAR file from the build stage into the runtime stage.
Only the compiled application is copied, not the full build environment.
Real Production Example
Consider a global online learning platform serving users from USA, UK, and India.
Microservices:
API Gateway
Course Service
Interview Service
Payment Service
Notification Service
Assessment Service
Each microservice uses a multi-stage Docker build.
api-gateway/Dockerfile
payment-service/Dockerfile
interview-service/Dockerfile
Production Multi-Stage Dockerfile for Spring Boot
FROM maven:3.9.6-eclipse-temurin-17 AS build
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline -B
COPY src ./src
RUN mvn clean package -DskipTests
FROM eclipse-temurin:17-jre-jammy
WORKDIR /app
RUN groupadd -r appuser && useradd -r -g appuser appuser
COPY --from=build /app/target/*.jar app.jar
RUN chown -R appuser:appuser /app
USER appuser
EXPOSE 8080
ENTRYPOINT ["java", "-XX:+UseContainerSupport", "-XX:MaxRAMPercentage=75.0", "-jar", "app.jar"]
Why This Dockerfile is Production Ready
| Feature | Benefit |
|---|---|
| Multi-stage build | Smaller final image |
| Dependency caching | Faster builds |
| JRE runtime image | Reduced attack surface |
| Non-root user | Improved security |
| Container-aware JVM | Better Kubernetes support |
Image Size Comparison
Without Multi-Stage Build
Image Size:
1.2 GB
With Multi-Stage Build
Image Size:
250 MB
In large enterprise systems, this saves huge storage and bandwidth costs.
Benefits in Kubernetes
Smaller images improve Kubernetes performance significantly.
Benefits
- Faster pod startup
- Faster image pull
- Reduced node storage usage
- Improved scaling speed
- Better cluster efficiency
Production Scaling Example
During Black Friday sales in USA or Diwali sales in India:
Normal Traffic:
2 payment containers
Heavy Traffic:
20 payment containers
Smaller Docker images allow Kubernetes to start additional containers faster.
Multi-Stage Build for Node.js Application
FROM node:20 AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80
Multi-Stage Build for React Application
FROM node:20 AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
Multi-Stage Build for Python Application
FROM python:3.11 AS build
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
COPY . .
FROM python:3.11-slim
WORKDIR /app
COPY --from=build /root/.local /root/.local
COPY . .
CMD ["python", "app.py"]
Common Multi-Stage Build Best Practices
- Use separate build and runtime stages
- Use lightweight runtime images
- Use specific image versions
- Cache dependencies properly
- Use non-root users
- Keep runtime stage minimal
- Use .dockerignore
- Scan images for vulnerabilities
Docker Layer Caching Optimization
Dependency files should be copied before source code for better caching.
Good Example
COPY pom.xml .
RUN mvn dependency:go-offline -B
COPY src ./src
Dependencies are cached unless pom.xml changes.
Security Benefits of Multi-Stage Builds
- Build tools removed from final image
- Reduced attack surface
- Smaller vulnerability footprint
- Cleaner runtime environment
Common Mistakes in Multi-Stage Builds
- Using full JDK in runtime image
- Copying unnecessary files
- Using latest tag
- Running as root
- Not using .dockerignore
- Missing dependency caching
Bad Example
FROM maven:latest
COPY . .
RUN mvn clean package
CMD ["java", "-jar", "target/app.jar"]
Problems
- Huge image size
- Contains Maven in production
- Contains source code
- Uses latest tag
CI/CD Pipeline with Multi-Stage Build
Developer Pushes Code
|
v
CI/CD Pipeline
|
v
Docker Multi-Stage Build
|
v
Optimized Docker Image
|
v
Image Security Scan
|
v
Push to Registry
|
v
Deploy to Kubernetes
Multi-Stage Build in Microservices
In microservices architecture, every service should ideally use multi-stage builds.
Microservice
|
v
Dockerfile
|
v
Multi-Stage Build
|
v
Optimized Runtime Image
Performance Benefits
| Area | Improvement |
|---|---|
| Image Size | Much smaller |
| Deployment Speed | Faster |
| Kubernetes Scaling | Improved |
| Security | Better |
| Cloud Storage | Reduced cost |
Interview Answer
Multi-stage Docker build is a Dockerfile optimization technique where multiple stages are used inside one Dockerfile. The first stage builds the application using build tools like Maven or Node.js, and the final stage copies only the required runtime artifacts into a lightweight image.
Multi-stage builds reduce image size, improve security, speed up deployments, and create production-ready Docker images suitable for Kubernetes, CI/CD, and cloud-native applications.
Production Checklist
[ ] Separate build and runtime stages
[ ] Use lightweight runtime image
[ ] Use non-root user
[ ] Use specific image versions
[ ] Cache dependencies properly
[ ] Use .dockerignore
[ ] Remove unnecessary files
[ ] Scan image for vulnerabilities
Useful Internal Links
- Docker Interview Questions
- DevOps Interview Questions
- Kubernetes Interview Questions
- Microservices Interview Questions
- AWS Interview Questions
- Spring Boot Interview Questions
Final Conclusion
Multi-stage Docker build is one of the most important Docker optimization techniques for modern production environments. It helps create smaller, cleaner, secure, and efficient Docker images by separating build and runtime stages.
In enterprise systems running on Kubernetes, AWS, Azure, Google Cloud, Docker Swarm, and cloud-native microservices platforms, multi-stage builds are considered a mandatory production best practice.