Why multi-stage builds reduce image size in Docker - Performance Analysis
We want to understand how the work done by Docker changes when using multi-stage builds.
Specifically, how does the build process scale with the number of steps and files involved?
Analyze the time complexity of the following Dockerfile using multi-stage builds.
FROM golang:1.20 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp
FROM alpine:latest
COPY --from=builder /app/myapp /myapp
CMD ["/myapp"]
This Dockerfile first builds the app in a full Go environment, then copies only the final app binary into a small Alpine image.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Copying and building source files in the builder stage.
- How many times: Each source file is processed once during the build.
As the number of source files grows, the build step takes longer because it processes more files.
| Input Size (n files) | Approx. Operations |
|---|---|
| 10 | Build processes 10 files |
| 100 | Build processes 100 files |
| 1000 | Build processes 1000 files |
Pattern observation: The build time grows roughly in direct proportion to the number of files.
Time Complexity: O(n)
This means the build time grows linearly with the number of source files processed.
[X] Wrong: "Multi-stage builds always make the build faster."
[OK] Correct: Multi-stage builds reduce final image size but the build time still depends on how many files are compiled and copied.
Understanding how build steps scale helps you explain trade-offs between build speed and image size in real projects.
What if we copied all source files into the final image instead of just the built binary? How would the time complexity and image size be affected?
Practice
Solution
Step 1: Understand multi-stage build process
Multi-stage builds use multiple FROM statements to separate build and runtime environments.Step 2: Identify file copying behavior
Only necessary artifacts are copied from build stages to the final image, excluding build tools and dependencies.Final Answer:
Because they copy only the necessary files from build stages to the final image -> Option CQuick Check:
Copying only needed files = smaller image [OK]
- Thinking all stages are combined fully
- Assuming all dependencies stay in final image
- Believing multi-stage builds speed up container runtime
builder in a multi-stage Dockerfile?Solution
Step 1: Recall Dockerfile COPY syntax for multi-stage
The correct syntax usesCOPY --from=stageName source destination.Step 2: Match syntax with options
COPY --from=builder /app/build /app matches the correct syntax exactly.Final Answer:
COPY --from=builder /app/build /app -> Option AQuick Check:
Use --from=stageName to copy files [OK]
- Using incorrect flags like --stage
- Trying to copy with colon syntax like builder:/path
- Reversing source and destination paths
FROM node:18 AS builder WORKDIR /app COPY package.json . RUN npm install COPY . . RUN npm run build FROM nginx:alpine COPY --from=builder /app/build /usr/share/nginx/html
Solution
Step 1: Analyze build and final stages
The builder stage installs node modules and builds the app. The final stage uses a lightweight nginx image.Step 2: Check what is copied to final image
Only the build output folder/app/buildis copied to nginx's html folder, excluding node modules and build tools.Final Answer:
The final image will be small because only the build output is copied -> Option AQuick Check:
Copying only build output reduces image size [OK]
- Assuming node modules are copied to final image
- Thinking final image includes builder base image
- Believing no files are copied at all
Solution
Step 1: Identify common causes of large final images
Copying unnecessary files like dependencies increases image size.Step 2: Match mistake to options
Copying the entire build directory including node_modules to the final stage describes copying the entire build directory including node_modules, which bloats the image.Final Answer:
Copying the entire build directory including node_modules to the final stage -> Option DQuick Check:
Copying unneeded files causes large images [OK]
- Thinking multiple FROM statements cause large images
- Believing missing stage names cause size issues
- Assuming lightweight base images increase size
Solution
Step 1: Understand multi-stage build for Go app
Build the app in a full Go environment, then copy only the compiled binary to a small base image.Step 2: Evaluate options for size reduction
FROM golang:1.20 AS builder WORKDIR /app COPY . . RUN go build -o app FROM alpine COPY --from=builder /app/app /app/app CMD ["/app/app"] uses golang image to build, then copies only the binary to alpine, minimizing final image size.Final Answer:
FROM golang:1.20 AS builder WORKDIR /app COPY . . RUN go build -o app FROM alpine COPY --from=builder /app/app /app/app CMD ["/app/app"] -> Option BQuick Check:
Build in full image, run in minimal image [OK]
- Building and running in same large image
- Trying to build in alpine without Go tools
- Copying full source code to final image
Ready to prove it?
Pass the test and this pattern moves unknown
