5.3.8MLOps & Deployment

Containerization with Docker

2,232 words10 min readdifficulty · medium5 backlinks

WHAT is containerization?

Figure — Containerization with Docker

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:

  1. 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.
  2. 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)
  1. Why do containers start far faster than VMs?
  2. Which line should come first: COPY requirements.txt or COPY . .? Why?
  3. What's the difference between an image and a container?
  4. Does EXPOSE publish a port? What does?
  5. 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:app your CMD typically 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?
A plain-text recipe of instructions used to build a Docker image.
What is a Docker image?
A frozen, read-only, layered template (filesystem + metadata) produced from a Dockerfile.
What is a Docker container?
A running, isolated instance of an image (image is to container as class is to object).
Why are containers lighter than VMs?
They share the host OS kernel via namespaces/cgroups instead of shipping a full guest OS.
Which kernel features give containers isolation?
namespaces (what a process can see) and cgroups (how much it can use).
Why copy requirements.txt before the source code in a Dockerfile?
So the expensive pip-install layer stays cached and isn't rebuilt on every code change.
What does each layer of an image represent?
The filesystem change produced by a single Dockerfile instruction, stacked via a union filesystem.
Rebuild cost after changing layer k of n layers?
Sum of costs from layer k to n (that layer and all layers after it must rebuild).
Does EXPOSE publish a port to the host?
No — it is metadata/documentation; -p host:container at docker run actually publishes.
What does docker run -p 8080:8000 mean?
Map host port 8080 to container port 8000 (host:container).
Difference between CMD and ENTRYPOINT?
ENTRYPOINT sets the fixed executable; CMD sets default, overridable arguments.
Why avoid the latest tag in production?
It's mutable and can silently point to a different image, breaking reproducibility; pin a version/SHA.
How do you persist data beyond a container's life?
Mount a volume with -v host:container; the container's writable layer is ephemeral.
Why prefer python:3.11-slim over python:3.11?
Smaller image, faster pulls, and reduced attack surface (fewer unused build tools).
Command to build an image tagged myapp:1.0 from current dir?
docker build -t myapp:1.0 .

Concept Map

solved by

packages

build

run

built from

enable

enable

drives

minimizes

shares

isolated via

makes containers

ships whole guest OS

contrasts with

It works on my machine problem

Docker

Code plus full environment

Dockerfile recipe

Image frozen template

Container live instance

Read-only layers

Layer caching

Content-addressed sharing

Order stable deps early, code last

Rebuild cost from first changed layer

Host Linux kernel

namespaces plus cgroups

Lightweight MBs, fast start

Virtual Machine

Heavy GBs, slow boot

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.

Go deeper — visual, from zero

Test yourself — MLOps & Deployment

Connections