Files
rootnode-academy/scenarios/data/docker-container-storage.json
T
ced4568andClaude Sonnet 5 682ef2de47 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]>
2026-08-26 17:08:14 -05:00

38 lines
3.0 KiB
JSON

{
"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" }
]
}