October 27, 2024


Multistage builds in Docker allow you to use multiple FROM statements in a single Dockerfile, where each stage can have its own base image and dependencies. The key benefit is that you can compile and build your application in an intermediate stage and then copy only the necessary artifacts to the final lightweight image.
This significantly reduces the final image size by excluding build tools, temporary files, and unnecessary dependencies.
Smaller Final Image Size
Improved Security
Faster Deployments
Cleaner Build Process
A typical multistage build has:
Before (Single-Stage Build – Bloated Image)
FROM golang:1.21
WORKDIR /app
COPY . .
RUN go build -o myapp
CMD ["./myapp"]Problem: The final image includes Go compiler (~800MB), source code, and build tools—unnecessary in production.
After (Multistage Build – Optimized Image)
# Stage 1: Build the application
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp
# Stage 2: Create a minimal runtime image
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/myapp .
CMD ["./myapp"]Result: Final image is based on alpine (~5MB) + the binary (a few MB).
Compiled Languages (Go, Rust, C++) Problem: Compilers increase image size.
Node.js Applications Problem: node_modules and dev dependencies bloat the image.
Example:
# Stage 1: Install dependencies and build
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# Stage 2: Production image
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/index.js"]Python Applications Problem: pip install includes dev packages.
Example:
# Stage 1: Install dependencies
FROM python:3.9-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
# Stage 2: Runtime image
FROM python:3.9-alpine
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "app.py"]Java (Maven/Gradle) Applications Problem: JDK is huge (~500MB), but only JRE is needed in production.
Example:
# Stage 1: Build with Maven
FROM maven:3.8.6 AS builder
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn package
# Stage 2: Run with JRE
FROM openjdk:17-jre-slim
WORKDIR /app
COPY --from=builder /app/target/myapp.jar .
CMD ["java", "-jar", "myapp.jar"]AS builder) for better readability..git or temp files)..dockerignore to exclude unnecessary files.Multistage builds are essential for optimizing Docker images. They:
Use them for compiled languages, Node.js, Python, and Java applications to keep your containers efficient and production-ready.
Would you like a real-world case study on this? Let me know! 🚀
Thank you for reading! I hope you found this post insightful. Stay curious and keep learning!
📫 Connect with me:
© 2025 Ayush Rudani