Bird
Raised Fist0
Dockerdevops~10 mins

Multi-stage builds concept in Docker - Step-by-Step Execution

Choose your learning style10 modes available
Process Flow - Multi-stage builds concept
Start: Define Stage 1
↓
Build app in Stage 1
↓
Define Stage 2
↓
Copy artifacts from Stage 1 to Stage 2
↓
Build final image in Stage 2
↓
Result: Smaller final image
Multi-stage builds use multiple steps in one Dockerfile to build and copy only needed files, making the final image smaller.
Execution Sample
Docker
FROM golang:1.20 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp

FROM alpine:latest
COPY --from=builder /app/myapp /usr/local/bin/myapp
CMD ["myapp"]
This Dockerfile builds a Go app in the first stage, then copies the binary to a small Alpine image in the second stage.
Process Table
StepActionStageFiles PresentImage Size Impact
1Start Stage 1 with golang basebuildergolang base filesLarge (includes build tools)
2Copy source code to /appbuildersource code + golang filesNo size change
3Run go build to create binarybuilderbinary + source + golang filesSize increases (binary added)
4Start Stage 2 with alpine basefinalalpine base filesSmall (minimal base)
5Copy binary from builder stagefinalbinary + alpine filesSize increases (only binary added)
6Set CMD to run binaryfinalbinary + alpine filesNo size change
7Build completesfinalfinal image with binary onlySmall final image (no build tools)
💡 Build ends with final image containing only necessary runtime files, excluding build dependencies.
Status Tracker
VariableStartAfter Step 3After Step 5Final
Files Presentgolang base filesgolang base + source + binaryalpine base + binaryalpine base + binary
Image Sizelargelargersmallsmall
Key Moments - 2 Insights
Why does the final image not include the source code or build tools?
Because in the execution_table at step 5, only the binary is copied from the builder stage to the final stage, so source code and build tools stay only in the builder stage.
How does multi-stage build reduce image size?
As shown in the execution_table, the final stage starts with a small base (alpine) and copies only the built binary, skipping all build dependencies, resulting in a smaller image.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table at step 3. What files are present in the builder stage after building?
AOnly the binary file
BOnly source code
CSource code, golang base files, and binary
DAlpine base files and binary
💡 Hint
Check the 'Files Present' column at step 3 in the execution_table.
At which step does the final image start to include the built binary?
AStep 5
BStep 4
CStep 2
DStep 7
💡 Hint
Look at the 'Files Present' column in the execution_table for when binary appears in the final stage.
If we copied source code instead of binary in step 5, how would the final image size change?
AIt would be smaller
BIt would be larger
CIt would stay the same
DIt would fail to build
💡 Hint
Refer to the variable_tracker showing image size changes related to files present.
Concept Snapshot
Multi-stage builds use multiple FROM statements in one Dockerfile.
Each stage can build or prepare files.
Later stages copy only needed artifacts from earlier stages.
This keeps the final image small by excluding build tools and source code.
Use --from=stage_name to copy files between stages.
Full Transcript
Multi-stage builds in Docker let you create smaller images by splitting the build into steps. First, you build your app in a stage with all tools. Then, you start a new stage with a small base image and copy only the built app from the first stage. This way, the final image has only what is needed to run the app, not the build tools or source code. The Dockerfile uses multiple FROM lines with stage names. The COPY command with --from= lets you copy files from one stage to another. This reduces image size and improves security.

Practice

(1/5)
1. What is the main purpose of using multi-stage builds in Docker?
easy
A. To automatically update Docker images from the internet
B. To run multiple containers simultaneously
C. To create smaller and cleaner Docker images by separating build and runtime stages
D. To speed up the Docker daemon startup

Solution

  1. Step 1: Understand multi-stage build concept

    Multi-stage builds allow splitting the Dockerfile into multiple stages, separating build tools from the final runtime environment.
  2. Step 2: Identify the benefit

    This separation helps reduce image size by excluding unnecessary build dependencies from the final image.
  3. Final Answer:

    To create smaller and cleaner Docker images by separating build and runtime stages -> Option C
  4. Quick Check:

    Multi-stage builds = smaller images [OK]
Hint: Remember: multi-stage builds reduce image size by separating stages [OK]
Common Mistakes:
  • Confusing multi-stage builds with running multiple containers
  • Thinking it speeds up Docker daemon startup
  • Believing it auto-updates images
2. Which of the following is the correct syntax to name a build stage in a Dockerfile?
easy
A. BUILD node AS builder
B. FROM node AS builder
C. STAGE node builder
D. COPY node AS builder

Solution

  1. Step 1: Recall Dockerfile syntax for naming stages

    The correct syntax to name a build stage is using FROM <image> AS <stage-name>.
  2. Step 2: Match options with syntax

    FROM node AS builder matches this syntax exactly, while others use invalid keywords.
  3. Final Answer:

    FROM node AS builder -> Option B
  4. Quick Check:

    Stage naming uses FROM ... AS ... [OK]
Hint: Use FROM ... AS ... to name stages in Dockerfile [OK]
Common Mistakes:
  • Using BUILD or STAGE keywords instead of FROM
  • Trying to name stages with COPY command
  • Missing AS keyword
3. Given this Dockerfile snippet, what will be the size impact on the final image?
FROM golang:1.20 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp

FROM alpine:latest
COPY --from=builder /app/myapp /usr/local/bin/myapp
CMD ["myapp"]
medium
A. The final image will be small because only the built binary is copied from the builder stage
B. The final image will be large because it includes the entire Go build environment
C. The final image will be empty because no files are copied
D. The final image will contain source code but no binary

Solution

  1. Step 1: Analyze the multi-stage build steps

    The first stage builds the Go binary using the full Go environment. The second stage uses a minimal Alpine image and copies only the binary from the builder stage.
  2. Step 2: Understand image size impact

    Because only the binary is copied, the final image excludes the Go build tools and source code, making it small.
  3. Final Answer:

    The final image will be small because only the built binary is copied from the builder stage -> Option A
  4. Quick Check:

    Copying only binary = smaller final image [OK]
Hint: Copy only needed files from builder to reduce image size [OK]
Common Mistakes:
  • Assuming the entire build environment is included in final image
  • Thinking no files are copied
  • Believing source code is copied without binary
4. Identify the error in this Dockerfile snippet using multi-stage builds:
FROM node:18 AS build
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
RUN npm install
CMD ["nginx", "-g", "daemon off;"]
medium
A. CMD syntax is incorrect
B. The first stage misses the AS keyword for naming
C. COPY command syntax is invalid
D. The second stage incorrectly runs 'npm install' which is not available in nginx image

Solution

  1. Step 1: Review commands in each stage

    The first stage builds the app correctly. The second stage uses nginx image, which does not have npm installed.
  2. Step 2: Identify invalid command in second stage

    Running 'npm install' in the nginx stage will cause an error because npm is not present.
  3. Final Answer:

    The second stage incorrectly runs 'npm install' which is not available in nginx image -> Option D
  4. Quick Check:

    npm commands require node environment, not nginx [OK]
Hint: Check if commands match the base image environment [OK]
Common Mistakes:
  • Assuming npm works in nginx image
  • Missing AS keyword (actually present here)
  • Misreading COPY syntax
  • Confusing CMD syntax
5. You want to build a Docker image for a Python app using multi-stage builds. The first stage installs dependencies and runs tests. The second stage copies only the app and dependencies for runtime. Which Dockerfile snippet correctly implements this?
hard
A.
FROM python:3.12 AS builder
WORKDIR /app
COPY requirements.txt .
RUN python -m venv venv && venv/bin/pip install -r requirements.txt
COPY . .
RUN venv/bin/pytest

FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /app /app
CMD ["venv/bin/python", "app.py"]
B.
FROM python:3.12
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
RUN pytest
CMD ["python", "app.py"]
C.
FROM python:3.12 AS builder
WORKDIR /app
COPY . .
RUN pytest

FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /app /app
RUN pip install -r requirements.txt
CMD ["python", "app.py"]
D.
FROM python:3.12 AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
RUN pytest

FROM python:3.12-slim
WORKDIR /app
COPY --from=builder /app /app
RUN pip install -r requirements.txt
CMD ["python", "app.py"]

Solution

  1. Step 1: Understand multi-stage build goals

    The first stage installs dependencies and runs tests. The second stage copies the app and dependencies for runtime only.
  2. Step 2: Analyze each option

    FROM python:3.12 AS builder
    WORKDIR /app
    COPY requirements.txt .
    RUN python -m venv venv && venv/bin/pip install -r requirements.txt
    COPY . .
    RUN venv/bin/pytest
    
    FROM python:3.12-slim
    WORKDIR /app
    COPY --from=builder /app /app
    CMD ["venv/bin/python", "app.py"]
    installs dependencies in a venv and tests in builder, then copies all of /app (including venv) to slim image without reinstalling.
    FROM python:3.12
    WORKDIR /app
    COPY requirements.txt .
    RUN pip install -r requirements.txt
    COPY . .
    RUN pytest
    CMD ["python", "app.py"]
    has no multi-stage build.
    FROM python:3.12 AS builder
    WORKDIR /app
    COPY . .
    RUN pytest
    
    FROM python:3.12-slim
    WORKDIR /app
    COPY --from=builder /app /app
    RUN pip install -r requirements.txt
    CMD ["python", "app.py"]
    installs dependencies after copying, which is inefficient.
    FROM python:3.12 AS builder
    WORKDIR /app
    COPY requirements.txt .
    RUN pip install -r requirements.txt
    COPY . .
    RUN pytest
    
    FROM python:3.12-slim
    WORKDIR /app
    COPY --from=builder /app /app
    RUN pip install -r requirements.txt
    CMD ["python", "app.py"]
    reinstalls dependencies in second stage, increasing image size.
  3. Final Answer:

    Uses virtualenv in builder stage to install dependencies and run tests, copies entire /app including venv to slim runtime -> Option A
  4. Quick Check:

    Install and test in builder, copy to slim runtime [OK]
Hint: Install and test in builder, copy only needed files to slim image [OK]
Common Mistakes:
  • Not using multi-stage builds
  • Reinstalling dependencies in final stage
  • Running tests in final image
  • Copying unnecessary files
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard