Reducing image size strategies in Docker - Time & Space Complexity
We want to understand how the time to build a Docker image changes when we apply strategies to reduce its size.
How does the build time grow as the image layers or files increase?
Analyze the time complexity of the following Dockerfile snippet.
FROM python:3.12-slim
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY app/ ./app/
RUN rm -rf /var/lib/apt/lists/*
CMD ["python", "./app/main.py"]
This Dockerfile installs dependencies and copies app files, then cleans cache to reduce image size.
Look for repeated or costly steps in the build process.
- Primary operation: Installing packages from requirements.txt (pip install).
- How many times: Once per build, but depends on number of packages listed.
The build time grows as the number of packages and files increases.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 packages/files | Low operations, fast build |
| 100 packages/files | About 10 times more operations, longer build |
| 1000 packages/files | Much longer build time, many more operations |
Pattern observation: Build time increases roughly in proportion to the number of packages and files processed.
Time Complexity: O(n)
This means the build time grows linearly with the number of packages and files included in the image.
[X] Wrong: "Removing cache files after installation makes the build time faster."
[OK] Correct: Removing cache reduces image size but does not speed up the installation step itself, so build time stays about the same.
Understanding how build time scales with image content helps you design efficient Dockerfiles and explain trade-offs clearly in real projects.
What if we split the installation of packages into multiple RUN commands? How would the time complexity change?
Practice
Solution
Step 1: Understand base image impact
The base image sets the starting size; smaller bases mean smaller final images.Step 2: Compare options
Alpine and slim variants are minimal, unlike full Ubuntu or adding unnecessary files.Final Answer:
Start with a small base image like Alpine or slim variants -> Option AQuick Check:
Small base image = smaller Docker image [OK]
- Using full OS images without slimming
- Installing unnecessary packages
- Adding extra files without need
Solution
Step 1: Understand package installation order
First update package lists, then install packages, finally clean cache to reduce image size.Step 2: Analyze commands
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/* updates, installs, then removes cache correctly; others have wrong order causing errors or no cleanup.Final Answer:
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/* -> Option DQuick Check:
Update -> install -> clean cache = correct order [OK]
- Cleaning cache before installing packages
- Skipping apt-get update
- Wrong command order causing errors
FROM node:18-alpine RUN apk add --no-cache git COPY . /app RUN npm install
Solution
Step 1: Analyze base image and package install
Using Alpine base and apk with --no-cache avoids cache files, keeping image small.Step 2: Consider npm install impact
npm install adds dependencies but starting from Alpine keeps overall size smaller than heavier bases.Final Answer:
The image will be small because Alpine and --no-cache reduce size -> Option AQuick Check:
Alpine + --no-cache = smaller image [OK]
- Assuming npm install always makes image large
- Ignoring --no-cache effect
- Not considering base image size
FROM python:3.12 RUN pip install flask RUN rm -rf /root/.cache/pipWhat is the main issue causing the large image?
Solution
Step 1: Understand Docker layers
Each RUN creates a new layer; cleaning cache in a separate RUN keeps cache in previous layer.Step 2: Combine commands to remove cache in same layer
Combining pip install and cache removal in one RUN prevents cache from persisting in earlier layers.Final Answer:
You should combine RUN commands to reduce layers -> Option BQuick Check:
Combine RUN commands to clean caches in one layer [OK]
- Cleaning cache in separate RUN commands
- Assuming base image size can't be optimized
- Believing package size can't be reduced
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"]
Solution
Step 1: Understand multi-stage build purpose
Build stage uses full Go image; final stage uses minimal Alpine with only binary copied.Step 2: Analyze final image contents
Only the compiled binary is copied, no source or build tools, keeping image small.Final Answer:
This multi-stage build compiles in golang image and copies only binary to Alpine, minimizing size -> Option CQuick Check:
Multi-stage build + minimal final image = small size [OK]
- Copying source files to final image
- Installing build tools in final image
- Building and running in same large image
Ready to prove it?
Pass the test and this pattern moves unknown
