fivenines
9/40

Guided Problem

MiniDock Build 06: Give Containers Private Writable Views

Time
20m
Level
foundation
Artifacts
not specified
Progress0%
Lesson 9 · Images

Union Filesystems

Design claim: A union filesystem gives each container a private writable view while retaining shared immutable image layers.

Starting model

  • You can store shared image content once and reject bytes that do not match their requested identity.
  • The useful vocabulary at this point is deliberately small: union filesystem, overlay, lower layer, upper layer.

Sharing and mutability pull in opposite directions

Many containers must start from the same image without copying its entire filesystem or allowing one container to modify another. Treat the release as data with identity and history, not as the accidental contents of one machine. Reuse is safe only after that data model is precise.

The tempting shortcut is straightforward: copy every image into a private directory before startup. The shortcut looks efficient until immutable history, shared content, or reproducibility becomes observable. Full copies waste time and storage, while direct writes to shared layers destroy image immutability and cross-container isolation. The constraint turns a convenient file operation into an identity or ordering bug.

Compose one view from different lifetimes

Think of each layer as a transparency sheet: lower sheets show through wherever upper sheets are blank. An overlay mount takes the image's layers as read-only lowerdirs (in manifest order), adds one empty writable upperdir, and exposes a merged view that the container mounts as /. Reads search top-down and return the first hit. Writes never touch the lowers — they land in the upper. Ten containers from one image share every read-only sheet and differ only in their thin upper layers.

Ordered read-only lower layers are merged with one container-private writable upper layer and presented as a single mount. The mechanism makes inputs and resulting content explicit, allowing later stages to reuse facts instead of trusting names or mutable directories.

Read the structure from references toward immutable content, noting where ordering or private state changes the meaning of an otherwise shared object.

Architecture — one overlay mount, seen from the container
  flowchart TB
    V["merged view — the container's /
(what the process sees)"] U["upperdir (writable, per-container)
changed: /etc/app.conf"] L3["lowerdir: app layer (RO)
/app/server"] L2["lowerdir: runtime layer (RO)
/usr/bin/python"] L1["lowerdir: base layer (RO)
/bin, /lib, /etc/app.conf"] V --- U U --- L3 L3 --- L2 L2 --- L1 style U fill:#fff8ec,stroke:#f2ddb0

It stacks immutable lower layers below a private upper layer and merged view. Its central claim is that container writes affect only the container's upper layer, never the shared image layers beneath it; the labels therefore describe authority rather than decorative grouping.

Copy only at the first write

The read path is the whole algorithm: check the upper, then each lower in order, first match wins. A file "modified" by the container exists twice — original in a lower, changed copy in the upper — and the upper always shadows:

Reads search the merged view; the first write to a lower-layer file copies it upward, and deletions are represented without changing the lower object. Follow identity through the operation and ask which completed fact authorizes each reuse or transition.

The second figure tests the same model in motion: it traces a read from lower content and a first write through copy-up.

Sequence — two reads through the stack
  sequenceDiagram
    participant P as Container process
    participant O as Overlay driver
    participant U as upperdir
    participant L as lowerdirs (top → bottom)
    P->>O: read /etc/app.conf
    O->>U: exists here?
    U-->>O: yes (container changed it)
    O-->>P: upper copy — shadows the original
    P->>O: read /usr/bin/python
    O->>U: exists here?
    U-->>O: no
    O->>L: search layers top-down
    L-->>O: found in runtime layer
    O-->>P: read-only original, shared by all containers
      

It traces a read from lower content and a first write through copy-up. The ordering is valid only when it continues to preserve the stated invariant under retries and interruption.

Private writes must remain private

Two route workers modify the same apparent path, so each must observe its own result while the shared image remains unchanged. A partial or stale result must remain distinguishable from a complete image state; otherwise the cache or store begins to lie.

Container writes affect only the container's upper layer, never the shared image layers beneath it. The invariant is phrased in bytes, ownership, or completed prefixes so it remains true across storage implementations.

Mount MiniDock's frozen and living halves

MiniDock gains cheap writable instances by composing layers instead of cloning releases. MiniDock can adopt the content rule without preselecting the learner's attachment point.

What carries forward

  • Container writes affect only the container's upper layer, never the shared image layers beneath it.
  • Give containers independent writable views without copying or mutating shared image layers.
  • The rejected shortcut remains a diagnostic: if the design starts depending on it again, the original constraint has probably been lost.
Next step

See what actually stuck.

Take the practice scenarios now.