Large Docker images slow down deployments, waste storage, and increase attack surface. Multi-stage builds are the solution. Learn how to dramatically reduce your container sizes.
The Problem with Single-Stage Builds
# Bad: 1.2GB image
FROM node:20
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
CMD ["node", "dist/index.js"]This includes dev dependencies, source files, and build tools — none of which are needed at runtime.
Multi-Stage Build Solution
# Good: 150MB image
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:20-alpine AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package*.json ./
RUN npm ci --only=production
USER node
CMD ["node", "dist/index.js"]Python Example
FROM python:3.12-slim AS builder
WORKDIR /app
RUN pip install --user --no-cache-dir -r requirements.txt
FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "main.py"]Go: The Ultimate Small Image
FROM golang:1.22 AS builder
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o server .
FROM scratch
COPY --from=builder /app/server /server
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
ENTRYPOINT ["/server"]This produces images as small as 10-15MB!
Best Practices
- Use
-alpineor-slimbase images - Order COPY commands from least to most frequently changed
- Use
.dockerignoreto exclude unnecessary files - Run as non-root user with
USERdirective - Use
npm ciinstead ofnpm installfor reproducible builds - Pin exact versions of base images
Size Comparison
Typical results with multi-stage builds:
- Node.js app: 1.2GB → 150MB (87% reduction)
- Python app: 900MB → 120MB (86% reduction)
- Go app: 800MB → 12MB (98% reduction)
Conclusion
Multi-stage builds are a must for production Docker images. They reduce size, improve security, and speed up deployments. Start using them in every Dockerfile you write.

Leave a Reply