Lesson 01 Code to Container
Theme:
Lesson 01 · Slide 1

Lesson 01 — Code to Container

From python app.py to docker run app — what actually happens under the hood.

Cloud & DevOps Module 1

Lesson 01 · Slide 2

The “works on my machine” problem

  • Different Python versions on different machines
  • Missing system libraries (libssl, libffi, …)
  • 3.11 passes CI, 3.12 breaks in staging
  • “But I tested it before pushing!”
  • Env vars set locally, absent in prod

Containers solve this by shipping the application and its environment as one immutable unit.

Lesson 01 · Slide 3

It's just Linux.

The kernel features powering containers have existed since Linux 2.6. Docker just made them ergonomic.

Lesson 01 · Slide 4

Namespaces in one slide

NamespaceWhat it isolates
pidProcess IDs — the container sees its app as PID 1
mountFilesystem mounts — the container's / is its own view
netNetwork interfaces, routes, iptables — own loopback, own routing
utsHostname and domain — independent of the host
userUID/GID mapping — root in container ≠ root on host
ipcShared memory and semaphores — isolated from host and other containers
Lesson 01 · Slide 5

cgroups in one slide

Without cgroups, one container can OOM the whole host. Docker's --cpus, --memory flags are cgroup files under the hood.

Lesson 01 · Slide 6

Container vs VM

ContainerVM
Boots inmillisecondstens of seconds
Overheadshares host kernelown kernel
Isolationnamespaces + cgroupshypervisor
Image sizetens of MBGB+
Per-host density100s–1000s10s
Lesson 01 · Slide 7

What Docker adds — Tooling, not magic.

Linux namespaces + cgroups have existed for over a decade. Docker made them ergonomic.

Lesson 01 · Slide 8

Images vs containers

Image

Read-only filesystem snapshot + metadata (env, CMD, entrypoint). Layered. Cacheable. Versioned by tag.

Container

A running (or stopped) instance of an image, with a writable top layer. Many containers can run from one image.

Build images. Run containers.

Lesson 01 · Slide 9

The minimal Dockerfile

FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]
Lesson 01 · Slide 10

docker build step by step

docker build -t url-shortener:0.1 .
Lesson 01 · Slide 11

docker run step by step

docker run --rm -p 8000:8000 url-shortener:0.1
Lesson 01 · Slide 12

What the running container looks like

docker ps                            # container listed with ID, name, ports
docker logs <id>                     # uvicorn's startup line
curl localhost:8000/health           # -> {"status":"ok"}
docker exec -it <id> /bin/sh        # drop into the container

# Inside the container:
ps -ef                               # only your app + maybe a shell
ls /app                              # app.py + requirements.txt
Lesson 01 · Slide 13

What lands in sample-app/ after this lesson

After Lesson 01: cloud-devops/sample-app/api/Dockerfile exists and
docker build -t url-api:0.1 . && docker run -p 8000:8000 url-api:0.1
boots the URL shortener locally.

Files added

  • api/Dockerfile

Files unchanged

  • api/app.py
  • api/requirements.txt
  • worker/worker.py
  • worker/requirements.txt
Lesson 01 · Slide 14

Recap & what’s next

Coming up: Lesson 02 — multi-stage builds, image-size optimization, and the Python-specific patterns that turn a 1.2 GB image into a 90 MB one.
1 / ?