100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace

What is a Docker Multi-Stage Build?

Learn how Docker multi-stage builds compile in one stage and ship a minimal final image, cutting size and attack surface for production.

mediumQ26 of 224 in DevOps Est. time: 6 minsLast updated:
Open Code Lab

Expected Interview Answer

A multi-stage Docker build uses multiple FROM instructions in one Dockerfile, where each stage can compile or prepare artifacts and only the final stage copies the specific files it needs into a small runtime image, discarding build tools and intermediate files entirely.

In a multi-stage build, an early stage typically uses a full SDK image to compile source code or install build-time dependencies, producing compiled binaries or bundled assets. A later stage starts fresh from a minimal base image, such as alpine or distroless, and uses COPY --from=<stage> to pull in only the compiled output, leaving the compiler, headers, and package caches behind in the discarded intermediate stage. This dramatically shrinks the final image size and reduces its attack surface, since build tooling and source code never ship to production. Named stages (FROM golang:1.22 AS builder) make the --from reference explicit and readable, and unused stages are simply never included in the final image layers.

  • Produces significantly smaller, more secure production images
  • Keeps build tools and source out of the shipped runtime image
  • Avoids maintaining a separate build script or CI-only Dockerfile
  • Still benefits from per-stage layer caching for faster rebuilds

AI Mentor Explanation

A multi-stage build is like a full training camp where players use heavy gym equipment and video analysis tools to prepare, but only their match-ready fitness and skills travel to the stadium on match day โ€” the gym equipment stays behind at the training facility. The camp (the builder stage) does the heavy lifting, but the stadium (the final image) only receives the polished, ready-to-perform player. Nobody hauls dumbbells and video screens onto the pitch. The result on match day is lean and focused only on what is needed to play.

Step-by-Step Explanation

  1. Step 1

    Define a builder stage

    FROM a full SDK image (e.g. golang, node) and run compilation or bundling steps there, named with AS builder.

  2. Step 2

    Define the runtime stage

    FROM a minimal base image (alpine, distroless, or scratch) to start the final image clean.

  3. Step 3

    Copy only the artifact

    Use COPY --from=builder to pull in compiled binaries or bundled assets, nothing else.

  4. Step 4

    Discard the builder

    The build stage and its tooling never become part of the final image layers or size.

What Interviewer Expects

  • Understanding that multiple FROM instructions define separate build stages
  • Knowledge of COPY --from=<stage> to move artifacts between stages
  • Awareness of the size and security benefits of excluding build tooling
  • Ability to name a real base image choice for the final minimal stage

Common Mistakes

  • Shipping the builder stage image instead of the minimal final stage
  • Not naming stages, making --from references fragile to reorder
  • Copying unnecessary files (like source code) into the final stage
  • Forgetting that each stage still needs its own correct base image

Best Answer (HR Friendly)

โ€œA multi-stage build lets us use a full, heavy toolchain to compile our application in one stage, then copy just the finished binary into a tiny, clean image for the next stage โ€” leaving all the compilers and build tools behind. That gives us a production image that is small, faster to deploy, and has a much smaller attack surface, without needing a separate build script outside Docker.โ€

Code Example

Multi-stage Dockerfile for a Go service
FROM golang:1.22 AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /out/server .

FROM alpine:3.19
COPY --from=builder /out/server /usr/local/bin/server
ENTRYPOINT ["/usr/local/bin/server"]

Follow-up Questions

  • How does a multi-stage build differ from using a separate CI build script?
  • When would you choose a distroless base over alpine for the final stage?
  • Can a multi-stage build still benefit from Docker layer caching?
  • How do you copy artifacts from more than one earlier stage?

MCQ Practice

1. What defines separate stages in a multi-stage Docker build?

Each FROM instruction starts a new build stage; a Dockerfile can define several stages before the final one.

2. How does the final stage retrieve an artifact from an earlier stage?

COPY --from references a previous stage by name or index to pull specific files into the current stage.

3. What is the main benefit of a multi-stage build for production images?

Only the final stage ships, so compilers, package managers, and intermediate files never reach the production image.

Flash Cards

What triggers a new build stage? โ€” Each FROM instruction in the Dockerfile.

How do you copy files between stages? โ€” COPY --from=<stage name or index>.

What is left out of the final image? โ€” Build tools, compilers, and intermediate files from earlier stages.

Typical final-stage base image? โ€” A minimal base like alpine, distroless, or scratch.

1 / 4

Continue Learning