Containerization with Docker
WHAT is containerization?

HOW an image is built: layers (derive it)
WHY layers? Docker builds an image one instruction at a time. Each
instruction (FROM, RUN, COPY, …) produces a new read-only layer stacked
on the previous one (a union filesystem). Two big wins fall out of this design:
- Caching — if a layer's instruction and its inputs are unchanged, Docker reuses the cached layer instead of rebuilding. Rebuilds go from minutes to seconds.
- Sharing — layers are content-addressed by hash, so two images sharing a base only store it once on disk / registry.
The canonical ML Dockerfile (built from first principles)
# 1. Base layer: a slim OS + Python. Small base = small image, less attack surface.
FROM python:3.11-slim
# 2. Set a working directory (all later paths are relative to it).
WORKDIR /app
# 3. Copy ONLY the dependency manifest first — this layer changes rarely.
COPY requirements.txt .
# 4. Install deps. --no-cache-dir keeps the layer small.
RUN pip install --no-cache-dir -r requirements.txt
# 5. NOW copy source code — this changes every commit, so it goes LAST.
COPY . .
# 6. Document the port the app listens on (metadata, not a firewall rule).
EXPOSE 8000
# 7. The default process to run when the container starts.
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]Common mistakes (Steel-manned)
Active recall
Recall Quick self-test (answer before expanding)
- Why do containers start far faster than VMs?
- Which line should come first:
COPY requirements.txtorCOPY . .? Why? - What's the difference between an image and a container?
- Does
EXPOSEpublish a port? What does? - Where does data go if you want it to survive container deletion?
Answers: 1) They share the host kernel — no guest OS to boot. 2)
requirements.txt first, so the pip-install layer stays cached across code
edits. 3) Image = frozen template; container = running instance of it. 4) No —
EXPOSE is metadata; -p at run time publishes. 5) A mounted volume.
Recall Feynman: explain to a 12-year-old
Imagine you baked a cake at home and it was perfect, but when your friend tries the same recipe their oven is different and it flops. Docker is like putting the cake and a mini kitchen in a sealed lunchbox — same oven, same ingredients, same everything — so it tastes identical no matter whose house you open it in. The recipe card is the Dockerfile, the sealed lunchbox is the image, and the moment you open one and start eating is a container. You can copy the lunchbox a hundred times and every one is the same.
Connections
- Kubernetes Orchestration — schedules & scales many containers.
- CI-CD Pipelines — builds and pushes images automatically on each commit.
- Model Serving with FastAPI — the
app:appyourCMDtypically runs. - Container Registries — Docker Hub / ECR / GCR store pushed images.
- Virtual Environments (venv, conda) — Python-level isolation; Docker is OS-level.
- Reproducibility in ML — pinned images = deterministic deployments.
What is a Dockerfile?
What is a Docker image?
What is a Docker container?
Why are containers lighter than VMs?
Which kernel features give containers isolation?
Why copy requirements.txt before the source code in a Dockerfile?
What does each layer of an image represent?
Rebuild cost after changing layer k of n layers?
Does EXPOSE publish a port to the host?
docker run actually publishes.What does docker run -p 8080:8000 mean?
Difference between CMD and ENTRYPOINT?
Why avoid the latest tag in production?
How do you persist data beyond a container's life?
Why prefer python:3.11-slim over python:3.11?
Command to build an image tagged myapp:1.0 from current dir?
docker build -t myapp:1.0 .Concept Map
Hinglish (regional understanding)
Intuition Hinglish mein samjho
Dekho, sabse bada problem yeh hota hai ki code "mere laptop pe to chal raha tha" par server pe crash ho jata hai — kyunki Python version, library versions, ya CUDA driver alag hote hain. Docker isi dard ka ilaaj hai. Docker aapke code ke saath uska pura environment (OS libraries, Python, pip packages, model weights) ek sealed box mein pack kar deta hai jise image bolte hain. Yeh image jahan bhi chalao, bilkul same behave karega — laptop, CI, ya cloud.
Teen cheezein yaad rakho: Dockerfile ek recipe hai (text instructions), image us recipe se bana frozen template hai, aur container us image ka running instance hai (jaise class aur object ka rishta). VM ke comparison mein container halka isliye hota hai kyunki wo host ka hi Linux kernel share karta hai — poora guest OS nahi bhejta, isliye MBs mein hota hai aur milliseconds mein start ho jata hai.
Ek 80/20 trick jo sabse zyada time bachati hai: Dockerfile mein pehle sirf
requirements.txt copy karo, phir pip install, aur uske baad COPY . .
karo. Kyun? Kyunki har layer cache hoti hai; agar aap code change karoge to sirf
last wali layer dubara banegi, mehngi pip-install wali layer cached rahegi. Agar
aap shuru mein hi COPY . . kar doge to har chhoti si code edit pe pura reinstall
hoga — bahut slow.
Do galtiyaan jo log karte hain: (1) EXPOSE 8000 likh ke sochte hain port khul
gaya — nahi, EXPOSE sirf documentation hai, actual publish -p 8080:8000 se hota
hai run time pe. (2) latest tag production mein use karna — yeh mutable hai, kal
kuch aur point kar sakta hai, isliye hamesha version ya git SHA pin karo. Aur agar
data survive karwana hai to volume mount karo (-v), warna container delete
hote hi writable layer ka data gayab.