Every tool replaced something worse — and is itself the wrong tool somewhere. For each big idea in this course: what life was like before it, its honest merits ✅ and demerits ❌, and where to use it 👍 vs where not 👎.
The server-room era: one app per physical machine, installed by hand from a wiki page — each server a unique "snowflake" nobody dared touch. Then virtual machines (~2000s): better packing, but every VM ships an entire OS — gigabytes on disk, minutes to boot, and the inside still drifted ("works on my VM"). Shipping software meant install docs, dependency checklists, and prayers. Docker (2013) made the lunchbox cheap: isolation without the whole OS.
Deploys were file transfers: rsync/FTP the code to each server, or bake "golden" VM snapshots/AMIs — slow to build, impossible to diff, mysterious to audit. "Which version is on server 7?" had no good answer. Registries turned deployment artifacts into versioned, fingerprinted, pull-from-anywhere objects.
A README with twelve "now run this" commands, per-developer shell scripts, and laptops that each worked slightly differently. Or Vagrant VMs: better, but heavyweight and slow. Compose made the whole dev stack one reviewable file and one command.
Either you built on the host and COPY'd artifacts in (host drift — the exact disease containers cure), or you kept two Dockerfiles + a glue script (the old "builder pattern"), or you just shipped the kitchen: 1GB+ production images with compilers, package managers and source code inside.
Either Docker Hub for everything (public by default, rate-limited, passwords on every node), or self-hosting registry:2 — meaning YOU patch it, scale it, store it, back it up and secure it. On AWS, that was a lot of undifferentiated pain next to the compute you already ran.