Multi-stage for different environments in Docker - Time & Space Complexity
We want to understand how the build time changes when using multi-stage Dockerfiles for different environments.
How does the number of build steps grow as we add more stages or complexity?
Analyze the time complexity of the following multi-stage Dockerfile snippet.
FROM node:18 AS base
WORKDIR /app
COPY package.json .
RUN npm install
FROM base AS development
COPY . .
CMD ["npm", "run", "dev"]
FROM base AS production
COPY . .
RUN npm run build
CMD ["npm", "start"]
This Dockerfile builds two environments: development and production, sharing common steps in the base stage.
Look for repeated steps or commands that run multiple times.
- Primary operation: Running
npm installin the base stage. - How many times: Once, shared by both development and production stages.
As the number of stages or environment setups increases, the build time grows mostly by the unique steps per stage.
| Input Size (n) | Approx. Operations |
|---|---|
| 2 stages | Base install + 2 environment-specific steps |
| 5 stages | Base install + 5 environment-specific steps |
| 10 stages | Base install + 10 environment-specific steps |
Pattern observation: The shared base step runs once, while unique steps add linearly with the number of stages.
Time Complexity: O(n)
This means build time grows linearly with the number of environment stages you add.
[X] Wrong: "Adding more stages will multiply the entire build time by the number of stages."
[OK] Correct: Because shared steps like npm install run only once and are reused, not repeated for each stage.
Understanding how multi-stage builds scale helps you explain efficient Dockerfile design and build optimization in real projects.
What if we duplicated the npm install step in each stage instead of sharing it? How would the time complexity change?
Practice
Solution
Step 1: Understand multi-stage build concept
Multi-stage builds separate the build environment from the runtime environment to avoid including unnecessary build tools in the final image.Step 2: Identify the benefit for different environments
This separation results in smaller, cleaner images optimized for the target environment, such as production.Final Answer:
To create smaller and cleaner Docker images by separating build and runtime stages -> Option CQuick Check:
Multi-stage builds = smaller images [OK]
- Thinking multi-stage runs multiple containers
- Believing it automatically updates images
- Assuming it increases image size
Solution
Step 1: Recall Dockerfile stage naming syntax
Docker uses the syntax 'FROM <image> AS ' to name a build stage.Step 2: Check each option
Only FROM node:18 AS build uses the correct 'FROM ... AS ...' syntax; others are invalid Dockerfile commands.Final Answer:
FROM node:18 AS build -> Option BQuick Check:
Stage naming = FROM ... AS ... [OK]
- Using 'STAGE' or 'BUILD' keywords incorrectly
- Forgetting the AS keyword
- Using 'WITH' instead of AS
FROM node:18 AS build RUN npm install FROM node:18-slim COPY --from=build /app/node_modules /app/node_modules
Solution
Step 1: Analyze the multi-stage build steps
The first stage installs dependencies with full Node image; the second stage uses a smaller Node image and copies only node_modules from the build stage.Step 2: Understand image size impact
Because only necessary files are copied, the final image is smaller than the full build environment image.Final Answer:
The final image will be smaller because it only copies needed files from build stage -> Option AQuick Check:
Copying from build stage reduces final image size [OK]
- Assuming all build tools are included in final image
- Thinking the build will fail due to missing files
- Believing final image equals build stage size
FROM python:3.12 AS build RUN pip install -r requirements.txt FROM python:3.12-slim COPY --from=builder /app /app
Solution
Step 1: Check stage names consistency
The first stage is named 'build' but COPY uses '--from=builder', which does not exist.Step 2: Verify COPY command correctness
The COPY syntax is correct, but the source stage name is wrong, causing build failure.Final Answer:
The stage name 'builder' does not match the first stage name -> Option DQuick Check:
Stage names must match exactly in COPY --from= [OK]
- Using wrong stage name in COPY
- Confusing syntax errors with naming errors
- Assuming base images cause this error
Solution
Step 1: Identify build and runtime separation
FROM golang:1.20 AS build WORKDIR /app RUN go build -o app . FROM alpine:latest COPY --from=build /app/app /app/app CMD ["/app/app"] uses golang image for building, then copies only the built app to a minimal alpine image for runtime.Step 2: Check other options for correctness
FROM alpine:latest AS build RUN apk add go WORKDIR /app RUN go build -o app . FROM golang:1.20 COPY --from=build /app/app /app/app CMD ["/app/app"] builds in alpine but runs in golang image, which is opposite of desired minimal runtime. Options C and D do not separate build and runtime stages.Final Answer:
Option A correctly uses multi-stage build for minimal runtime image -> Option AQuick Check:
Build heavy, run minimal = FROM golang:1.20 AS build WORKDIR /app RUN go build -o app . FROM alpine:latest COPY --from=build /app/app /app/app CMD ["/app/app"] [OK]
- Building in minimal image causing slow builds
- Running heavy image in production
- Not separating build and runtime stages
Ready to prove it?
Pass the test and this pattern moves unknown
