Module 7: Multi-Stage Docker Builds
🔹 What is a Multi-Stage Build?
A multi-stage build in Docker allows you to use multiple FROM statements in a single Dockerfile. Each stage can focus on a different task—for example, building source code in one stage and creating a lightweight final image in another.
👉 This helps keep the final image small, secure, and efficient by removing unnecessary build dependencies.
🔹 Why Multi-Stage Builds?
✅ Reduce image size by excluding compilers, build tools, and intermediate files.
✅ Better security: only production-ready files go into the final image.
✅ Easier to maintain and extend compared to separate Dockerfiles.
🔹 How Multi-Stage Builds Work
Build Stage – Use a base image with build tools (Node.js, Java, Maven, etc.) to compile code.
Final Stage – Copy only the required artifacts (e.g., binaries, JAR files, compiled app) into a minimal runtime image (like
alpineordistroless).
🔹 Example 1: Node.js Multi-Stage Build
# Stage 1: Build stage
FROM node:18 AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# Stage 2: Production stage
FROM node:18-alpine
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY package*.json ./
RUN npm install --only=production
CMD ["node", "dist/index.js"]
✅ Final image is much smaller than keeping build tools inside.
🔹 Example 2: Java + Maven Multi-Stage Build
# Stage 1: Build stage
FROM maven:3.9.6-eclipse-temurin-17 AS build
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests
# Stage 2: Runtime stage
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=build /app/target/myapp.jar .
CMD ["java", "-jar", "myapp.jar"]
✅ The final image only contains the JAR file and a lightweight JRE.
🔹 Best Practices for Multi-Stage Builds
Use
alpineordistrolessimages for smaller runtime environments.Use
.dockerignoreto exclude unnecessary files (e.g.,.git,node_modules).Keep your Dockerfile readable by naming stages (
AS build).Always pin versions of base images for consistency.
👉 This module teaches how to optimize Docker images, making them lightweight, production-ready, and efficient.
