Back to course

Lesson 21: Advanced Dockerfile: Multi-Stage Builds

Docker Zero to Hero: The Complete Containerization Course for Beginners

Lesson 21: Advanced Dockerfile: Multi-Stage Builds

One common problem is that compiling code (e.g., Java, Go, React) requires large tooling images (SDKs, compilers, npm packages), but these tools are not needed in the final runtime environment.

The Problem: Bloated Images

If you compile a Go application in a standard Go image, the final resulting image will include the entire compiler toolchain and dependencies, making the image unnecessarily large.

The Solution: Multi-Stage Builds

Multi-stage builds allow you to define multiple FROM statements in a single Dockerfile. You copy only the necessary artifacts (the compiled binary or final static files) from the 'builder' stage to the final, lightweight 'runtime' stage.

Example: Building a Go Application

dockerfile

--- STAGE 1: Builder Stage ---

FROM golang:1.21-alpine AS builder

WORKDIR /app COPY go.mod go.sum ./ RUN go mod download COPY . .

Compile the static binary

RUN CGO_ENABLED=0 go build -o /app/my_app .

--- STAGE 2: Final Runtime Stage ---

Use a minimal image (alpine) which doesn't include the compiler

FROM alpine:latest

WORKDIR /root/

Copy only the compiled binary from the 'builder' stage

COPY --from=builder /app/my_app .

Define the final executable command

CMD ["./my_app"]

Benefits:

  • Smaller Images: The final image is dramatically smaller because it only contains the executable and necessary OS libraries.
  • Improved Security: Less attack surface because development tools are absent from the production image.