What You'll Learn
Beginner
- What multi-stage builds are and why they matter
- How to separate build tools from runtime
- Real examples in Go, Java, and Node.js
The Problem Multi-Stage Solves
Without multi-stage, your production image includes build tools, source code, and temporary artifacts — none needed at runtime.
The Solution: Multiple Stages
A multi-stage Dockerfile has multiple FROM lines. Each FROM starts a new stage. You COPY --from only what you need.
Example: Go Application
Dockerfiledockerfile
# Stage 1: Build
FROM golang:1.21 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o myapp .
# Stage 2: Runtime
FROM alpine:3.18
RUN apk add --no-cache ca-certificates
WORKDIR /app
COPY --from=builder /app/myapp .
CMD ["./myapp"]Result: ~22 MB image instead of ~800 MB.
Example: Node.js Application
Dockerfiledockerfile
# Stage 1: Build
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: Runtime (only production deps)
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist
CMD ["node", "dist/server.js"]Practical Exercise
Write a single-stage Dockerfile — check the size
Rewrite as multi-stage — compare the size
Run
docker images to see the differenceTest that the multi-stage image still works
Key Takeaways
- Multi-stage builds use multiple
FROMlines — each is a new stage. COPY --from=stagecopies artifacts between stages.- Build in a heavy image, run in a tiny image.
- Typical size reduction: 10-50x smaller.
- Name stages with
ASfor readability.
Comments
Comments
Post a Comment