Skip to main content

Command Palette

Search for a command to run...

Module 7: Multi-Stage Docker Builds

Updated
2 min readView as Markdown

🔹 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

  1. Build Stage – Use a base image with build tools (Node.js, Java, Maven, etc.) to compile code.

  2. Final Stage – Copy only the required artifacts (e.g., binaries, JAR files, compiled app) into a minimal runtime image (like alpine or distroless).


🔹 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 alpine or distroless images for smaller runtime environments.

  • Use .dockerignore to 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.


Mastering Docker: The Complete Guide

Part 7 of 14

This series takes you on a journey from Docker basics to advanced real-world applications. You’ll learn everything from running your first container, building images, and managing networks, to multi-container setups, CI/CD pipelines.

Up next

Module 8: Docker Compose Advanced

So far, you’ve learned how to use Docker Compose to define and run multi-container applications. In this module, we’ll go deeper into advanced features that make Compose powerful for real-world projects. 🔹 1. Environment Variables in docker-compose...

More from this blog

D

DevOps Launchpad - Learn DevOps,Cloud, and Kubernetes

26 posts