From python app.py to docker run app — what actually happens under the hood.
Cloud & DevOps Module 1
Containers solve this by shipping the application and its environment as one immutable unit.
The kernel features powering containers have existed since Linux 2.6. Docker just made them ergonomic.
| Namespace | What it isolates |
|---|---|
pid | Process IDs — the container sees its app as PID 1 |
mount | Filesystem mounts — the container's / is its own view |
net | Network interfaces, routes, iptables — own loopback, own routing |
uts | Hostname and domain — independent of the host |
user | UID/GID mapping — root in container ≠ root on host |
ipc | Shared memory and semaphores — isolated from host and other containers |
--cpus 0.5 → 50% of one core; maps to /sys/fs/cgroup/cpu/--memory 256m → OOM-kill the container if it exceeds 256 MB--blkio-weight → relative IO bandwidth per container--pids-limit → cap process count (fork-bomb defence)Without cgroups, one container can OOM the whole host. Docker's --cpus, --memory flags are cgroup files under the hood.
| Container | VM | |
|---|---|---|
| Boots in | milliseconds | tens of seconds |
| Overhead | shares host kernel | own kernel |
| Isolation | namespaces + cgroups | hypervisor |
| Image size | tens of MB | GB+ |
| Per-host density | 100s–1000s | 10s |
Dockerfile: a deterministic recipe for assembling a layered imagedocker run, docker exec, docker logs, docker psLinux namespaces + cgroups have existed for over a decade. Docker made them ergonomic.
Read-only filesystem snapshot + metadata (env, CMD, entrypoint). Layered. Cacheable. Versioned by tag.
A running (or stopped) instance of an image, with a writable top layer. Many containers can run from one image.
Build images. Run containers.
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"]
FROM — base image (every container starts from one)WORKDIR — sets default directory; auto-creates if missingCOPY requirements.txt first — keeps the pip-install layer cached on code editsRUN — runs at build time; result becomes a layerCMD — exec form; uvicorn is PID 1, gets SIGTERM cleanlydocker build step by stepdocker build -t url-shortener:0.1 .
Dockerfile top to bottomdocker run step by stepdocker run --rm -p 8000:8000 url-shortener:0.1
--memory / --cpus specified)-p 8000:8000 — forwards host port into the container's net namespace via iptables NATdocker 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
sample-app/ after this lessonAfter 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.
api/Dockerfileapi/app.pyapi/requirements.txtworker/worker.pyworker/requirements.txt