⏱️ Slide Timing: 1 min - Welcome to the session — frame Docker as the standard answer to "it works on my machine" - Promise: by the end, everyone will have built and run their own container - No prior Docker experience needed — just basic Python familiarity (scripts, pip, running a `.py` file) - Bridge: start with the pain every developer has hit before showing the fix
⏱️ Slide Timing: 3 min - Most relatable pain point in software — everyone has hit this within their first few group projects - Analogy: sending a cake recipe without the oven settings, pan size, or ingredient brands - Root cause: software depends on an invisible stack of system state that never travels with the code - Docker's fix: package the entire environment, not just the code ❓ Ask: "Has anyone had code that ran on one machine but broke on another?"
⏱️ Slide Timing: 4 min - Key word: "portable" — like a shipping container in logistics - Same metal box, same locking mechanism — any ship, truck, or crane can handle it - Docker doesn't virtualise an entire OS — it shares the host kernel, which is what makes it lightweight - Became the de facto standard for shipping web apps, APIs, and data pipelines
⏱️ Slide Timing: 4 min - Class/object analogy lands immediately — students already know this from Python - Layers matter for speed: change only your code, and Docker reuses the cached dependency layers - Docker Hub has ready-made images: python:3.11-slim, node:20, postgres — a huge head start - "slim" variants strip out compilers and docs — smaller image, faster to pull and run
⏱️ Slide Timing: 4 min - Left path: the local dev loop — build once, run many times - Right path: `push` to Docker Hub, a teammate `pull`s the exact same image and runs it - Dockerfile is the only thing you write by hand — Image and Container are generated - Docker Hub is optional for local experiments, essential once you're sharing with a team or deploying
⏱️ Slide Timing: 4 min - Left: each VM carries a full guest OS and kernel — that's why VMs are measured in GBs and boot in minutes - Right: all containers share the host kernel — only the app and its libraries are isolated, so images are MBs and start in seconds - VMs still win when you need a genuinely different OS or kernel-level security isolation - For everyday app/API development, containers are the lighter, faster default
⏱️ Slide Timing: 3 min - Docker Desktop is the easiest path for students on Mac/Windows - The hello-world container is a real pull + run — confirms the whole pipeline works end to end - Common gotcha on macOS/Windows: Docker Desktop must be running (whale icon in the menu bar/tray) - Have everyone run `docker run hello-world` live before moving on
⏱️ Slide Timing: 4 min - `-t` names the image — always give it a meaningful name, not the default hash - `-it` is the most useful debugging flag: drops you into a shell inside the container - `docker ps -a` shows stopped containers too — the `-a` is the flag students forget - Muscle memory to build: build → run → inspect → iterate
⏱️ Slide Timing: 4 min - Line order matters for caching: dependencies change rarely, code changes often - Putting `COPY . .` before `RUN pip install` busts the pip cache on every single code change - `python:3.11-slim` strips compilers and docs, cutting image size roughly 60% - CMD vs ENTRYPOINT: CMD is the default command (overridable at `docker run`); ENTRYPOINT always runs
⏱️ Slide Timing: 3 min - `pyfiglet` is deliberately not installed on the host — it only exists inside the image - The point: nobody runs `pip install pyfiglet` on their laptop, yet it works identically for everyone - This exact pattern scales directly to a real app — swap `app.py` for a Flask/FastAPI server and you have a deployable service - Students follow along on their own laptop for this one
⏱️ Slide Timing: 4 min - First build takes longer — it downloads the base image and installs pyfiglet - Second build is fast — Docker reuses the cached dependency layer since requirements.txt hasn't changed - Note "Platform: Linux" even on macOS/Windows hosts — that's the container's own isolated OS view - `--rm` auto-deletes the container after it exits — handy for one-off demo runs - Challenge: edit the message in app.py, rebuild, and notice only the last layer rebuilds ❓ Ask: "What would you need to change to containerise your own script instead?"
⏱️ Slide Timing: 3 min - Volume mounts (`-v`) matter whenever data should outlive the container or come from the host - Environment variables are the clean way to inject secrets — never `COPY .env` into an image - `-p` maps a host port to a container port — visit `localhost:8000` to reach a containerised API - These three flags cover the majority of real-world `docker run` usage
⏱️ Slide Timing: 3 min - Docker is the common currency of the modern software stack, not just an ML or web-dev thing - CI pipelines run tests inside the exact same container that later ships to production — no more "passed CI, broke in prod" - Every major cloud platform (AWS ECS/Fargate, Azure Container Apps, Google Cloud Run) runs container images directly - Tie back to opening problem: pushing an image replaces a page of manual setup instructions
⏱️ Slide Timing: 3 min - `.dockerignore` works exactly like `.gitignore` — same syntax, same idea, different purpose - Secrets baked into an image layer are recoverable even after later layers "remove" them — never bake them in - The "vanishing files" pitfall is the most common first surprise — reinforce that containers are ephemeral by default
⏱️ Slide Timing: 1 min - Highest priority to bookmark: docs.docker.com/get-started — interactive tutorial, no install needed - python:3.11-slim is the go-to base image for pure Python projects - Docker Hub search is the fastest way to find a pre-built image for almost any framework
⏱️ Slide Timing: 2 min - Close the loop back to the opening problem: Docker is the fix for "works on my machine" - The three-command mantra covers most day-to-day usage - Practice prompt: containerise the `docker_demo` app right now, then try swapping in a script of your own