feat(root04): author Containers & Docker

Adds all 8 ROOT 04 modules (why containers exist, images & containers, Docker CLI, container
networking, container storage, Dockerfile & image build, Docker Compose, containers →
Kubernetes) — 43 activities, using the nested Docker Engine Phase 6D built and tested. Modules
1, 2, and 8 are conceptual (no lab by design) — the honest bridge module (M8) explicitly names
what Kubernetes adds beyond what this course already taught, without re-teaching Kubernetes
itself.

Adds 5 new hands-on Docker scenarios plus 2 MCQs, all against the real nested Docker Engine:
docker-cli-basics (run/exec/inspect a real container), docker-container-networking (a genuine
"works internally, unreachable from host" port-publishing failure, diagnosed and fixed by
recreating the container with the correct `-p` flag), docker-container-storage (a real
destroy/recreate cycle proving named-volume persistence, not just described), docker-build-image
(a real Dockerfile, a real build, a real custom image run), and docker-compose-multiservice (a
real two-service Compose application with a real published port). All tested end-to-end via the
real scenario-validation API, including negative tests.

Wires rootnode-containers-assessment (2 required + 4 random-draw scenarios) using the existing
Phase 3B assessment engine.

This completes the entire ROOT_ Foundations sequence (ROOT 01-04) — see
docs/PHASE6E_ROOT_FOUNDATIONS_COMPLETION.md.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
2026-08-26 17:08:14 -05:00
co-authored by Claude Sonnet 5
parent e68b6f445a
commit 682ef2de47
45 changed files with 1970 additions and 0 deletions
@@ -0,0 +1,51 @@
# Why Containers Exist
## "It works on my machine"
Every engineer has heard this sentence, and it names a real, expensive problem: an application
that runs perfectly on one machine fails on another because of differences in installed
libraries, OS versions, configuration, or dozens of other environmental details that are easy to
overlook and hard to fully document.
## The problem, precisely
- **Dependency inconsistency** — an app needs Python 3.11 and a specific set of libraries; the
production server has Python 3.9 and different library versions.
- **Non-repeatability** — setting up a working environment by hand, following a README, drifts
over time and between people — "works on my machine" is often true because "my machine" has
accumulated years of undocumented manual setup.
- **Deployment friction** — moving an application from a developer's laptop to a test server to
production means repeating fragile manual setup multiple times, each an opportunity for drift.
## Containers: package the application AND everything it needs, together
A **container** packages an application with its exact dependencies, libraries, and
configuration into one deployable unit — the same container that ran on a developer's laptop
runs, byte-for-byte identically, on a test server or in production. "It works on my machine"
becomes "it works in this container," which is true everywhere that container runs.
## VM vs. container — genuinely different, not just "containers are lighter VMs"
A **virtual machine** virtualizes an entire computer, including its own full operating system
kernel — heavier, slower to start, but with very strong isolation. A **container** shares the
HOST machine's kernel and only isolates the application's process, filesystem view, and network
— dramatically lighter and faster to start (seconds vs. minutes), with somewhat different
isolation properties than a full VM (a well-understood, documented tradeoff, not a hidden flaw).
Neither is strictly "better" — they solve overlapping but distinct problems, and real production
systems often use both together (VMs providing strong host isolation, containers providing fast,
consistent application packaging on top).
## Instructor Notes
**Lesson goal:** Motivate containers through the real, felt problem ("it works on my machine")
before any Docker command — mirrors ROOT 03's "why version control exists" opener.
**Approximate timing:** 12 minutes read; 8 minutes live.
**Common misconception to watch for:** describing containers as simply "lightweight VMs" —
they share the host kernel, which is a genuine architectural difference, not just a size
difference.
**Discussion question:** "Has anyone experienced 'it works on my machine' personally, on either
side of that conversation?" (Real stories make this lesson's premise concrete before the
technical content begins.)
@@ -0,0 +1,49 @@
# Demonstration: What "Shares the Host Kernel" Actually Looks Like
## OBSERVE
```
$ uname -r
5.15.0-real-host-kernel
$ docker run --rm alpine:3.19 uname -r
5.15.0-real-host-kernel
```
## HYPOTHESIS
Predict: would a real virtual machine show the SAME kernel version as its host, the way this
container just did?
## INSPECT
A real VM runs its OWN independent kernel — it would very likely show a DIFFERENT version (or
even a different OS entirely) than its host, because a VM virtualizes the hardware and boots a
complete, separate operating system on top of it.
## CHANGE
```
$ docker run --rm ubuntu:22.04 uname -r
5.15.0-real-host-kernel
```
Even a completely different container OS (`ubuntu` here, vs. `alpine` before) STILL reports the
exact same kernel version — because there's only ONE real kernel involved, the host's.
## VERIFY
This is the concrete, observable meaning of "containers share the host kernel": no matter what
container image you run, `uname -r` always reports the same real kernel underneath — this is
exactly why containers start in a fraction of a second (no separate kernel to boot) and exactly
the tradeoff the lesson named.
## Instructor Notes
**Demo goal:** Make "shares the host kernel" a concrete, checkable fact rather than an abstract
architectural claim.
**Approximate timing:** 8 minutes live.
**Common mistake to watch for:** assuming different container images run different kernels
because their USERSPACE (installed tools, package manager) looks completely different — the
kernel underneath is unified regardless.
@@ -0,0 +1,33 @@
# Knowledge Check: Why Containers Exist
---
**1. What real problem does "it works on my machine" name?**
*Answer:* Dependency/environment inconsistency between where an application was developed and
where it actually needs to run — differences in libraries, versions, and configuration that are
easy to overlook and hard to fully document by hand.
---
**2. What's the actual architectural difference between a container and a virtual machine, not
just "containers are smaller"?**
*Answer:* A container shares the host machine's kernel and only isolates the application's
process/filesystem/network view. A VM virtualizes an entire computer, including running its own
separate kernel — a genuinely different isolation model, not just a size difference.
---
**3. Why do containers start so much faster than VMs?**
*Answer:* A container doesn't boot a separate operating system/kernel — it starts a process
using the ALREADY-RUNNING host kernel, while a VM has to boot an entire independent OS from
scratch.
## Instructor Notes
**Facilitation:** Question 2 is the one worth confirming explicitly — many students carry the
misconception "container = tiny VM" past this point without correction.
**Approximate timing:** 5 minutes.
@@ -0,0 +1,26 @@
# Reflection: You Now Know What Problem You're About to Solve, Hands-On
## Reflection questions
1. Think back to ROOT 01's "how computers run software" module. How does today's lesson refine
your understanding of what a "process" actually is?
2. Do you expect containers to make the Linux/process/networking skills from ROOT 01-02 less
relevant, or MORE relevant? Why?
## Real Ops takeaway
**Every skill from ROOT 01-02 — processes, filesystems, networking — transfers directly into
containers, because a container is built from exactly those same primitives, just isolated
differently.** You are not about to learn an unrelated new subject; you're about to see the
Linux fundamentals you already have applied through Docker's specific tooling. Module 2 starts
that translation.
This module is complete. Continue to the next module.
## Instructor Notes
**Discussion questions for a live classroom:** question 2's honest answer is "more relevant" —
worth stating explicitly, since students sometimes assume containers are an alternative to
Linux fundamentals rather than built directly on top of them.
**Approximate timing:** 5-8 minutes live discussion; 5 minutes self-paced writing.