Guides
How to Shrink a Docker Image with Multi-stage Builds
By Ravindra Bagale, DevOps trainer · LinkedIn · Published: · Last updated:
Shrink Docker images with a builder stage and a slim runtime that only COPY --from the artifact. Add .dockerignore and measure size.
Friends, builders need compilers; production needs only the binary. Chala mitrano — two stages, one slim image.
मित्रांनो, builder ला compiler लागतो; production ला फक्त binary. Chala mitrano — दोन stages, एक slim image.
मित्रों, builder को compiler चाहिए; production को सिर्फ binary। Chala mitrano — दो stages, एक slim image।
Quick answer
Hold this vertical picture:
- Write a fat single-stage file.
- Split builder and slim runtime.
- COPY --from the artifact only.
- Add .dockerignore.
- Measure with docker images.
Language: English · मराठी · हिंदी
Multi-stage shrink
Why shrink images
Big images slow EKS pulls and waste ECR storage — every Amazon retail peak notices it.
Why: Faster deploys and smaller attack surface.
What: Multi-stage: build then copy artifact.
How: Write fat vs slim files and measure.
Example 1: Fat Dockerfile sketch
Type this:
mkdir -p /tmp/ms && printf "%s\n" "FROM python:3.12" "WORKDIR /app" "COPY . ." "RUN pip install flask" "CMD [\"python\",\"app.py\"]" > /tmp/ms/Dockerfile.fat && wc -l /tmp/ms/Dockerfile.fat
You will see:
What it means: One stage keeps build tools — often hundreds of MB.
Example 2: Multi-stage sketch
Type this:
printf "%s\n" "FROM python:3.12 AS builder" "WORKDIR /app" "COPY requirements.txt ." "RUN pip install --user -r requirements.txt" "FROM python:3.12-slim" "WORKDIR /app" "COPY --from=builder /root/.local /root/.local" "COPY app.py ." "CMD [\"python\",\"app.py\"]" > /tmp/ms/Dockerfile && wc -l /tmp/ms/Dockerfile
You will see:
What it means: Builder installs; slim runtime copies the install path only.
Example 3: Tiny app files
Type this:
printf "%s\n" "flask==3.0.0" > /tmp/ms/requirements.txt && printf "%s\n" "print(\"ok\")" > /tmp/ms/app.py && ls /tmp/ms
You will see:
Dockerfile Dockerfile.fat app.py requirements.txt
What it means: Minimal app files like many Infosys internal tools.
Concept 1: Two stages
AS builder then a slim FROM.
Why: Compilers must not ship to prod.
What: FROM ... AS builder; FROM slim; COPY --from=
How: Keep installs in builder.
Example 2: Multi-stage sketch
Type this:
printf "%s\n" "FROM python:3.12 AS builder" "WORKDIR /app" "COPY requirements.txt ." "RUN pip install --user -r requirements.txt" "FROM python:3.12-slim" "WORKDIR /app" "COPY --from=builder /root/.local /root/.local" "COPY app.py ." "CMD [\"python\",\"app.py\"]" > /tmp/ms/Dockerfile && wc -l /tmp/ms/Dockerfile
You will see:
What it means: Builder installs; slim runtime copies the install path only.
Example 7: React or Node pattern
Type this:
printf "%s\n" "COPY --from=builder /app/dist /usr/share/nginx/html"
You will see:
COPY --from=builder /app/dist /usr/share/nginx/html
What it means: Builder runs npm build; nginx stage serves dist.
Example 8: Pin base tags
Type this:
printf "%s\n" "Prefer python:3.12-slim not latest" "Pin digests in production when policy asks"
You will see:
Prefer python:3.12-slim not latest
Pin digests in production when policy asks
What it means: latest drifts — TCS prod pipelines pin versions.
Concept 2: dockerignore and measure
Ignore junk; compare sizes.
Why: Secrets and .git must not enter layers.
What: .dockerignore; docker images; docker history
How: Measure on your EC2 lab.
Example 4: Add .dockerignore
Type this:
printf "%s\n" ".git" "__pycache__" "*.pyc" ".env" "Dockerfile.fat" > /tmp/ms/.dockerignore && cat /tmp/ms/.dockerignore
You will see:
.git
__pycache__
*.pyc
.env
Dockerfile.fat
What it means: dockerignore keeps secrets and junk out of every stage.
Example 5: Build if Docker exists
Type this:
command -v docker >/dev/null && docker build -t lab-flask:slim /tmp/ms || printf "%s\n" "docker not running here — files ready for your EC2 lab"
You will see:
docker not running here — files ready for your EC2 lab
What it means: On Amazon Linux EC2 with Docker, the same build tags a slim image.
Example 6: Compare mental sizes
Type this:
printf "%s\n" "FAT: full python image often 1GB+ with deps" "SLIM: python slim + user install often a few hundred MB"
You will see:
FAT: full python image often 1GB+ with deps
SLIM: python slim + user install often a few hundred MB
What it means: Exact numbers vary — always check docker images on your host.
Example 10: Check layers
Type this:
printf "%s\n" "docker history lab-flask:slim" "Huge RUN pip in final stage means COPY --from failed"
You will see:
docker history lab-flask:slim
Huge RUN pip in final stage means COPY --from failed
What it means: Final history should not show compiler installs.
Concept 3: Traps and card
Avoid copying the whole tree into runtime.
Why: One bad COPY undoes the shrink.
What: Copy artifact only; non-root when possible.
How: Use the shrink card in reviews.
Example 9: Non-root sketch
Type this:
printf "%s\n" "RUN useradd -r appuser" "USER appuser"
You will see:
RUN useradd -r appuser
USER appuser
What it means: Prefer non-root in the final stage when the base allows it.
Example 11: Common trap
Type this:
printf "%s\n" "TRAP: COPY . . in final stage pulls node_modules again"
You will see:
TRAP: COPY . . in final stage pulls node_modules again
What it means: Copy only the artifact folder into runtime.
Example 12: Shrink card
Type this:
printf "%s\n" "1 builder 2 slim runtime 3 COPY --from 4 .dockerignore 5 docker images"
You will see:
1 builder 2 slim runtime 3 COPY --from 4 .dockerignore 5 docker images
What it means: Memorize for Flipkart Docker interview rounds.
Shrink card
- Builder stage with tools
- Slim runtime base
- COPY --from=builder artifact
- .dockerignore
- docker images / history
Suppose: React on nginx
npm build in builder; nginx:alpine copies dist.
Suppose: Spring Boot
Maven builder; JRE copies the jar.
Ravindra Bagale's Tip
At Amazon and Flipkart container reviews, image size and .dockerignore are the first checklist items after a green build.
Amazon/Flipkart container reviews मध्ये green build नंतर image size आणि .dockerignore पहिली checklist.
Amazon/Flipkart container reviews में green build के बाद image size और .dockerignore पहली checklist।
Check yourself (quiz)
Q1. What is multi-stage?
Build in one FROM, copy artifact into a slim FROM
Q2. Why .dockerignore?
Keep .git, secrets and junk out of every stage
Q3. Common trap?
COPY . . into the final stage pulls build junk back
Q4. How to measure?
docker images and docker history
Q5. Pin tags?
Yes — avoid latest in production
Q6. Why slim for EKS?
Faster pulls and less storage
Reading tracking
Mark this guide when you finish. Your browser remembers it on this device.
Builder → slim → COPY --from → dockerignore → measure.
Did you understand? Let us try it once more.
Frequently asked questions
What is multi-stage?
Build in one stage; copy the result into a slim stage.
Why .dockerignore?
Stops junk and secrets entering layers.
How to copy from builder?
COPY --from=builder /path /path
How to check size?
docker images and docker history
React pattern?
npm build in builder; nginx serves dist
Why pin tags?
latest drifts between builds