Building Docker Images with DockerfileLesson 2.3
Multi-stage Docker builds for smaller production images
multi-stage build, builder stage, final stage, COPY --from, image size reduction, Go binary, compiled artifacts
Shipping Only What Production Needs
Development tools โ compilers, build systems, test runners โ should never be in a production image. Multi-stage builds let you compile in one image and copy only the output into a minimal final image.
Example: Node.js with a Build Step
# Stage 1: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build # Produces /app/dist
# Stage 2: Production
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY --from=builder /app/dist ./dist
CMD ["node", "dist/server.js"]
The final image contains no TypeScript compiler, no devDependencies, no source files โ only the compiled output and production dependencies.
Example: Go Binary
FROM golang:1.22 AS builder
WORKDIR /src
COPY . .
RUN go build -o /bin/api ./cmd/api
FROM scratch
COPY --from=builder /bin/api /api
CMD ["/api"]
scratch is an empty image โ zero OS. The Go binary is fully self-contained. This produces images under 10MB versus 800MB+ with the Go SDK. Check final image size with docker images myapp.
