Guided Problem
MiniDock Build 15: Complete One Run or Clean It Up
- Time
- 30m
- Level
- advanced
- Artifacts
- not specified
docker run: The Full Picture
Design claim: A run request is a coordinated workflow whose partial steps require explicit ownership and cleanup.
Starting model
- You can serialize lifecycle commands and events into one legal container state.
- The useful vocabulary at this point is deliberately small: run coordinator, root filesystem, network attachment, runtime bundle.
Convenient syntax hides distributed work
One user command must resolve content, allocate storage and networking, persist state, start a process, and attach streams. Runtime behavior unfolds over time, so state and ownership must remain valid after the initiating request has returned.
The tempting shortcut is straightforward: implement run as one opaque call that either returns a container or throws. The shortcut confuses one command or connection with the longer-lived process and resources it happens to touch. The workflow crosses independently failing subsystems, and earlier allocations remain when a later step fails. Asynchronous exit, retry, disconnect, or timeout exposes that mismatch immediately.
Give the workflow a durable spine
This is the course's midpoint summit — no new concepts, only composition. The order is forced by data dependencies: you can't mount layers you don't have, can't write a runtime bundle without a mounted rootfs and a network to reference, can't start what isn't created. Each lesson you've done is one arrow:
The daemon decomposes run into ordered, idempotent stages with a container record that coordinates progress and compensation. The mechanism records the durable fact separately from transient control and lets events update the model when reality changes.
Read the static view as custody and the dynamic view as evidence crossing that custody boundary.
flowchart TB
A["1· resolve image
(reference store; pull if missing — L15)"]
B["2· mount overlay
(image lowers + new upper — L9)"]
C["3· allocate network
(sandbox + IP — Part 6)"]
D["4· write bundle
(rootfs path + config: cmd, env, limits)"]
E["5· runtime chain
(manager → shim → runc — L3)"]
F["6· kernel setup
(namespaces L4, cgroups L5, seccomp L6)"]
G["7· exec app — state: Running (L18)"]
A --> B --> D
C --> D
D --> E --> F --> G
It places image, storage, network, runtime, and stream services around one coordinator. Its central claim is that one run request produces one completed container or a recoverable record of every resource that still needs cleanup; the labels therefore describe authority rather than decorative grouping.
Establish prerequisites before exposing success
This is the course's midpoint summit — no new concepts, only composition. The order is forced by data dependencies: you can't mount layers you don't have, can't write a runtime bundle without a mounted rootfs and a network to reference, can't start what isn't created. Each lesson you've done is one arrow:
Resolve image, prepare snapshot, create metadata, allocate network, assemble an OCI bundle, invoke the runtime chain, and connect the requested streams. The sequence matters because lifecycle decisions made from stale evidence become illegal or destructive operations.
The second figure tests the same model in motion: it orders allocation and launch while making the failure and cleanup edges visible.
sequenceDiagram
participant CLI as CLI
participant D as Daemon
participant N as Net allocator
participant M as Manager
participant S as Shim
participant R as Runtime
CLI->>D: run api:2.2
D->>D: resolve tag, then check layers (pull if missing)
D->>D: mount overlay: lowers + fresh upper
D->>N: create sandbox, assign IP
N-->>D: eth0 ready
D->>M: create container (bundle)
M->>S: spawn shim
S->>R: create: namespaces, cgroups, filters
R->>R: exec app, then runtime exits
S-->>M: running (pid)
M-->>D: started
D-->>CLI: container id, attached stream
It orders allocation and launch while making the failure and cleanup edges visible. The ordering is valid only when it continues to preserve the stated invariant under retries and interruption.
Failure leaves obligations, not mystery
Network allocation succeeds but process creation fails, so retry or cleanup must not leak an endpoint or create a duplicate container. The failure case is authoritative input to the state model, not an exception to be hidden behind a successful command response.
One run request produces one completed container or a recoverable record of every resource that still needs cleanup. The reusable rule keeps process reality, operator intent, and retained resources from collapsing into one status flag.
Assemble MiniDock's run path
MiniDock now composes prior subsystems through an explicit transaction-like workflow without pretending they share one transaction. MiniDock must preserve the lifecycle guarantee while leaving the current integration move to the learner.
What carries forward
- One run request produces one completed container or a recoverable record of every resource that still needs cleanup.
- Produce either one supervised running container or no resources from a failed run attempt.
- The rejected shortcut remains a diagnostic: if the design starts depending on it again, the original constraint has probably been lost.
See what actually stuck.
Take the practice scenarios now.