0
0
DockerHow-ToBeginner · 3 min read

How to Use Multi-Stage Build in Docker for Smaller Images

Use FROM multiple times in a Dockerfile to create separate build stages. Copy only the needed artifacts from the build stage to the final stage using COPY --from=, which results in smaller, cleaner images.
📐

Syntax

A multi-stage Dockerfile uses multiple FROM statements to define separate stages. Each stage can have a name for easy reference. Use COPY --from=<stage-name> to copy files from one stage to another.

This helps separate the build environment from the runtime environment.

dockerfile
FROM golang:1.20 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp

FROM alpine:3.18
COPY --from=builder /app/myapp /usr/local/bin/myapp
CMD ["myapp"]
💻

Example

This example shows a Go application built in one stage and copied to a minimal Alpine image in the final stage. It demonstrates how multi-stage builds reduce image size by excluding build tools from the final image.

dockerfile
FROM golang:1.20 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp

FROM alpine:3.18
RUN apk add --no-cache ca-certificates
COPY --from=builder /app/myapp /usr/local/bin/myapp
CMD ["myapp"]
⚠️

Common Pitfalls

  • Not naming stages makes COPY --from= harder to read and maintain.
  • Copying unnecessary files from build stage increases final image size.
  • Forgetting to install runtime dependencies in the final stage causes runtime errors.
dockerfile
### Wrong (no stage name, copying whole directory)
FROM node:18
WORKDIR /app
COPY . .
RUN npm install && npm run build

FROM node:18-alpine
COPY --from=0 /app /app
CMD ["node", "/app/dist/index.js"]

### Right (named stage, copy only build output)
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package*.json ./
RUN npm install --production
CMD ["node", "dist/index.js"]
📊

Quick Reference

CommandDescription
FROM AS Start a new build stage with a name
COPY --from= Copy files from a previous stage
RUN Run commands in the current stage
CMD ["executable"]Set the default command for the final image

Key Takeaways

Use multiple FROM statements to create separate build and runtime stages.
Name your build stages for clarity and easier file copying.
Copy only necessary files from build to final stage to keep images small.
Install runtime dependencies only in the final stage to avoid bloated images.
Multi-stage builds help produce efficient, secure, and smaller Docker images.