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:
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"id": "docker-container-storage",
|
||||
"title": "Prove Data Survives a Container's Death — With a Volume",
|
||||
"category": "Containers",
|
||||
"isolation_type": "shared_namespace",
|
||||
"difficulty": "Medium",
|
||||
"type": "task",
|
||||
"weight": 6,
|
||||
"description": "## Prove Data Survives a Container's Death — With a Volume\n\nA container's own writable layer is disposable — data written there disappears when the container is destroyed. A named VOLUME is different.\n\n**Your task:**\n\n1. Create a named volume: `docker volume create storage-lab-vol`\n2. Run a container named `storage-lab-app` from `alpine:3.19` (keep it running with `sleep 3600`), mounting the volume at `/data`\n3. Write a file `/data/file.txt` containing exactly `persisted-data`, inside the container\n4. Destroy the container completely (`docker rm -f storage-lab-app`)\n5. Recreate it with the SAME name, SAME image, and the SAME volume mount\n6. Confirm `/data/file.txt` still contains `persisted-data` — proving the volume, not the container, is what actually held the data",
|
||||
"hints": [
|
||||
{
|
||||
"title": "Creating and mounting a volume",
|
||||
"body": "`-v <volume-name>:<path-in-container>` mounts a named volume at a path inside the container — data written there lives in the volume, independent of the container's own lifecycle.",
|
||||
"command": "docker volume create storage-lab-vol\ndocker run -d --name storage-lab-app -v storage-lab-vol:/data alpine:3.19 sleep 3600\ndocker exec storage-lab-app sh -c 'echo persisted-data > /data/file.txt'"
|
||||
},
|
||||
{
|
||||
"title": "Destroying and recreating",
|
||||
"body": "Removing the container does NOT remove the volume — recreating a container with the same `-v` flag reattaches the exact same data.",
|
||||
"command": "docker rm -f storage-lab-app\ndocker run -d --name storage-lab-app -v storage-lab-vol:/data alpine:3.19 sleep 3600\ndocker exec storage-lab-app cat /data/file.txt"
|
||||
}
|
||||
],
|
||||
"setup_commands": [
|
||||
{ "command": "docker rm -f storage-lab-app 2>/dev/null; docker volume rm storage-lab-vol 2>/dev/null; true" },
|
||||
{ "command": "docker pull alpine:3.19" }
|
||||
],
|
||||
"validation": {
|
||||
"commands": [
|
||||
{ "description": "storage-lab-vol volume exists", "command": "docker volume inspect storage-lab-vol --format '{{.Name}}' 2>/dev/null", "expected_output": "storage-lab-vol", "match": "exact" },
|
||||
{ "description": "storage-lab-app is running and mounts the volume at /data", "command": "docker inspect storage-lab-app --format '{{range .Mounts}}{{.Name}}:{{.Destination}} {{end}}' 2>/dev/null", "expected_output": "storage-lab-vol:/data", "match": "contains" },
|
||||
{ "description": "the data genuinely survived a container destroy/recreate cycle", "command": "docker exec storage-lab-app cat /data/file.txt 2>/dev/null", "expected_output": "persisted-data", "match": "exact" }
|
||||
]
|
||||
},
|
||||
"default_namespace": "default",
|
||||
"teardown_commands": [
|
||||
{ "command": "docker rm -f storage-lab-app 2>/dev/null; docker volume rm storage-lab-vol 2>/dev/null; true" }
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user