What is a multi-stage build and why does it matter for image size?
Learn what a Docker multi-stage build is, how COPY --from works, and why it dramatically shrinks image size while improving security and deploy speed.
Expected Interview Answer
A multi-stage build uses multiple FROM statements in a single Dockerfile so you can compile or build an application in a heavy 'builder' stage and then copy only the finished artifacts into a lean final image, dramatically reducing image size.
Each FROM begins a new stage, and later stages can COPY --from an earlier stage to pull in just the outputs (a compiled binary, bundled assets) while leaving behind compilers, dev dependencies, and build caches. This keeps build-time tooling out of the runtime image, which shrinks size, reduces the attack surface, and speeds up pulls and deploys. Before multi-stage builds, teams needed separate Dockerfiles or brittle scripts to achieve the same slim result.
- Drastically smaller final images
- Build tools and dev dependencies excluded from runtime
- Smaller attack surface improves security
- Faster image pulls and deployments
- Single Dockerfile instead of build scripts
- Named stages make builds readable and cacheable
AI Mentor Explanation
A multi-stage build is like net practice before a match. In the nets you use bowling machines, cones, throwdowns, and coaches — a whole workshop of gear. But onto the field you carry only the bat and pads that matter. The heavy training apparatus stays behind, just as build tools stay in the builder stage while only the finished 'player' walks into the lean match-day image.
Step-by-Step Explanation
Step 1
Define a builder stage
Start with a full-featured base image (e.g. golang or node) and name it: FROM node:20 AS builder.
Step 2
Build the application
Install dependencies and compile or bundle inside the builder stage, where all the tooling is available.
Step 3
Start a lean final stage
Add a second FROM using a minimal runtime base such as alpine, distroless, or nginx.
Step 4
Copy only artifacts
Use COPY --from=builder to pull just the built output into the final stage, leaving tooling behind.
Step 5
Set the runtime command
Define CMD/ENTRYPOINT in the final stage; only this last stage becomes the shipped image.
What Interviewer Expects
- Correct use of multiple FROM statements and named stages
- Understanding COPY --from to move artifacts between stages
- Why build tools should not ship in the runtime image
- Connection between smaller images and security/deploy speed
- Awareness of minimal base images like distroless or alpine
Common Mistakes
- Copying the entire builder stage instead of just artifacts
- Leaving dev dependencies installed in the final stage
- Forgetting to name stages, making COPY --from fragile
- Using a heavy base image for the final stage unnecessarily
- Thinking multi-stage builds slow down or complicate the pipeline
Best Answer (HR Friendly)
“A multi-stage build lets you assemble an app using all the heavy tools in one step, then package only the finished result into a small, clean image. It's like cooking in a messy kitchen but serving only the plated dish, which makes the final product smaller, faster to ship, and more secure.”
Code Example
# Stage 1: build with full tooling
FROM node:20 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Stage 2: lean runtime image
FROM nginx:1.27-alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]Follow-up Questions
- How does COPY --from reference a previous stage?
- What is a distroless image and why use it as a final stage?
- Can you copy from an external image with COPY --from=nginx:latest?
- How do multi-stage builds interact with Docker's build cache?
- How would you use a target stage to build just part of a Dockerfile?
MCQ Practice
1. What is the main purpose of a multi-stage build?
Multi-stage builds separate the build environment from the runtime so only finished artifacts land in a lean final image.
2. Which instruction moves artifacts from an earlier stage into the final stage?
COPY --from=<stage> copies files from a named or numbered earlier build stage into the current one.
3. Why do smaller images improve security?
Fewer packages and tools in the image means fewer potential vulnerabilities to exploit.
Flash Cards
What defines a multi-stage build? — Multiple FROM statements in one Dockerfile, building in one stage and copying artifacts into a lean final stage.
How do you move outputs between stages? — Use COPY --from=<stage-name-or-index> to copy only the needed artifacts.
Why does it shrink image size? — Compilers, dev dependencies, and build caches stay in the builder stage and never reach the final image.
Which stage becomes the shipped image? — Only the last stage (or a chosen --target) is built into the final image.
Name a minimal final base image — Alpine, distroless, or a purpose-built runtime like nginx:alpine.