fivenines
7/40

Theory Tutorial

Anatomy of an Image

Time
10m
Level
not specified
Artifacts
theory + practice
Progress0%
Lesson 7 · Images

Anatomy of an Image

Design claim: An image is a graph of immutable filesystem content plus runtime metadata, not a single opaque archive.

Starting model

  • You can trace allowed and prohibited operations through independent runtime security guards.
  • The useful vocabulary at this point is deliberately small: manifest, config, layer, digest.

A runnable release needs two kinds of truth

A release must describe both the exact root filesystem bytes and the process configuration needed to start them. 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: package the application as one tar archive and infer runtime behavior at launch. The shortcut looks efficient until immutable history, shared content, or reproducibility becomes observable. One archive cannot independently share layers, verify ordered content, or declare entrypoint, environment, and platform metadata. The constraint turns a convenient file operation into an identity or ordering bug.

Separate content from configuration

Unpack any image and you find exactly three kinds of object. The manifest is a small JSON index: "this image = this config + these layers, in this order." The config holds everything needed to run: default command, environment, working directory, exposed ports. The layers are tar archives of filesystem changes — layer 1 might be a base OS, layer 2 your runtime, layer 3 your app. Splitting run-metadata (config) from file-content (layers) is the key move: two images can share every layer yet run different commands.

An OCI-style manifest identifies a config object and an ordered list of layer descriptors, each addressed by digest. 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 image, unpacked
  flowchart LR
    TAG["tag: myapp:1.0"] --> M["manifest (JSON)
the index"] M -- "1 ×" --> CFG["config (JSON)
cmd, env, ports, workdir"] M -- "ordered list" --> L1["layer 1 (tar)
base OS files"] M --> L2["layer 2 (tar)
language runtime"] M --> L3["layer 3 (tar)
your app files"] style M fill:#eaf1fe,stroke:#1d63ed

It separates manifest, config, and ordered layer objects. Its central claim is that filesystem order and runtime configuration are explicit, immutable inputs to container creation; the labels therefore describe authority rather than decorative grouping.

Resolve the graph before mounting it

When the engine needs image myapp:1.0, it never trusts the name — it walks the tree. Tag → manifest digest, manifest → config and layer digests, digests → blobs on disk. Every arrow is a hash lookup, which Lesson 8 turns into a superpower:

A client resolves a reference to a manifest, reads configuration, obtains each layer in order, and assembles the root filesystem before applying process settings. 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 resolves a reference through metadata and content before process startup.

Sequence — resolving a tag inside the local store
  sequenceDiagram
    participant E as Engine
    participant RS as Reference store (tags)
    participant BS as Blob store
    E->>RS: what is myapp:1.0?
    RS-->>E: manifest digest sha256:ab12…
    E->>BS: fetch blob ab12… (the manifest)
    BS-->>E: manifest JSON
    E->>BS: fetch config blob + each layer blob it lists
    BS-->>E: config + layers
    note over E: image fully resolved —
ready to become a rootfs (Lesson 9)

It resolves a reference through metadata and content before process startup. The ordering is valid only when it continues to preserve the stated invariant under retries and interruption.

Shared bytes do not imply shared behavior

The same layer digests appear under two manifests with different configuration, so content sharing must not conflate runtime metadata. A partial or stale result must remain distinguishable from a complete image state; otherwise the cache or store begins to lie.

Filesystem order and runtime configuration are explicit, immutable inputs to container creation. The invariant is phrased in bytes, ownership, or completed prefixes so it remains true across storage implementations.

Give MiniDock an image graph

MiniDock can now treat an image as a verifiable object graph rather than a special file. MiniDock can adopt the content rule without preselecting the learner's attachment point.

What carries forward

  • Filesystem order and runtime configuration are explicit, immutable inputs to container creation.
  • Read an image graph and identify which object owns runtime metadata and layer order.
  • 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.