You can run FastAPI or Flask on a laptop. Production needs a reproducible process: same Python, same deps, same port, no “works on my CUDA driver.” Docker packages that process as an image. Module 18.3 will care about GPU images; here we containerize the API wrapper around Module 18.1 SDKs.
Next: Kubernetes runs many containers. Redis / Celery will appear as sibling containers in Compose. Do not confuse Docker with “we deployed”—see Deployment.
Learning Objectives
By the end of this lesson, students should be able to:
- Explain image vs container vs registry in one sentence each.
- Write a multi-stage-friendly Dockerfile for a FastAPI AI wrapper.
- Pass secrets via env/runtime, never
ENV OPENAI_API_KEY=sk-...in the image. - Use Compose to run API + Redis locally.
- Know why GPU images (
nvidia-container-toolkit) differ from CPU API images. - Hand a tagged image to Kubernetes without rewriting the app.
Docker is a container toolchain: a Dockerfile builds an image (immutable filesystem + default command); a container is a running instance isolated by the kernel (namespaces/cgroups). A registry (Docker Hub, GHCR, ECR) stores tagged images. Containers are not VMs; they share the host kernel. They are also not Kubernetes—K8s schedules containers.
What Goes in the Image
| Include | Exclude |
|---|---|
App code, requirements.txt / lockfile | API keys, .env, customer data |
| Uvicorn/Gunicorn entrypoint | --reload, Jupyter, A1111 checkpoints |
| Non-root user, pinned base digest | latest as a production pin if you can avoid it |
HEALTHCHECK hitting /health | Training datasets “just in case” |
FastAPI Dockerfile + Compose Sketch
CPU API Image vs GPU Runtime
This lecture (wrapper)
- Slim Python + Uvicorn
- Calls OpenAI/Anthropic/Gemini
- No CUDA in the image
Self-host infer (18.3)
- CUDA base or nvidia runtime
- vLLM / TGI / Comfy worker
- GPU + drivers on host
Compose vs K8s
- Compose: laptop / single VM
- K8s: replicas, probes, rollouts
- Same image tag in both
Docker buys you
- Reproducible deploys and CI
- Parity: laptop ≈ staging process
- Isolation from host Python chaos
Docker does not buy you
- Auth, TLS, or cost meters by itself
- Multi-node scheduling (Kubernetes)
- A substitute for secret managers
Related Lectures
| Lecture | Role |
|---|---|
| FastAPI / Flask | The process inside the image |
| Kubernetes | Run many copies of this image |
| Redis | Sibling container in Compose |
| Deployment | Registries, envs, rollouts |
| GPU | When the image needs CUDA |
“I dockerized it, so it’s secure.” Images can still leak keys in layers (ENV, docker history, copied .env). Second: latest is not a version. Third: bind-mounting the host Docker socket into the app container is not a feature for students. Fourth: a 20 GB A1111 image is not the same job as a 150 MB FastAPI wrapper—do not cargo-cult GPU bases for a chat proxy.
Knowledge Check
- Short Answer: Image vs container? Answer: Image is the immutable template; container is a running instance.
- True/False: Bake
OPENAI_API_KEYinto the Dockerfile withENV. Answer: False—inject at runtime / secret store. - Multiple Choice: Typical API CMD: (a) uvicorn main:app --host 0.0.0.0 --port 8000, (b) jupyter notebook, (c) k-means. Answer: (a).
- Short Answer: Why a
.dockerignore? Answer: Keep secrets, git, caches, and huge weights out of the build context. - True/False: Docker is the same thing as Kubernetes. Answer: False—K8s schedules containers.
- Multiple Choice: Redis in Compose is usually: (a) a sibling service, (b) a sampler, (c) a LoRA. Answer: (a).
- Short Answer: Why run the process as a non-root user? Answer: Limit blast radius if the app is compromised.
- True/False: A CPU slim image is enough for an OpenAI-proxy API. Answer: True (no local GPU required).
- Multiple Choice: Next lecture: (a) Kubernetes, (b) Whisper, (c) PCA. Answer: (a).
- Short Answer: Name one thing Docker does not replace. Answer: Any of: authentication, TLS, monitoring, K8s scheduling, secret management.
Key Takeaways
- Image = reproducible API process; container = running copy.
- Slim Python + Uvicorn; secrets at runtime only.
- Compose for API+Redis locally; same tag for K8s later.
- GPU bases are for self-host infer, not chat proxies.
- Next: Kubernetes.
Lab: Dockerize the FastAPI chat app. Prove .env is not in the image (docker history / exec env). Add Redis via Compose and print REDIS_URL from /health.
Whiteboard: Laptop Python vs image layers vs registry vs K8s Pod. Circle where the API key lives (runtime secret, not layer).
Recap: Docker packages the API. Orchestrate next with Kubernetes.