Skip to content
OCI Image Format
step 1/5

Reading — step 1 of 5

Read

~1 min readFilesystems & Images

OCI Image Format

A Docker image isn't a single file — it's a content-addressable bundle of three things:

  1. A manifest (JSON) listing a config blob and a list of layer blobs.
  2. A config (JSON): architecture, OS, env vars, entrypoint, history.
  3. Layers: tarballs, each addressed by sha256:... of their content.

Everything is content-addressed: change one byte in the config, the config's sha256 changes, the manifest's config.digest field changes, the manifest's own sha256 changes — and the image now has a new ID.

Example manifest (OCI v1, abridged)

{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.manifest.v1+json",
  "config": {
    "mediaType": "application/vnd.oci.image.config.v1+json",
    "digest": "sha256:...",
    "size": 7023
  },
  "layers": [
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
      "digest": "sha256:...",
      "size": 32654
    }
  ]
}

DiffID vs digest

  • digest = sha256 of the compressed blob (what the registry stores and transfers)
  • diffID = sha256 of the uncompressed tar (what the container runtime references when stacking layers)

The config holds the diffIDs (so layer stacking is content-addressable independent of compression), while the manifest holds the digests (so transfer is content-addressable).

For this exercise: simulate building a manifest — hash layers, accumulate the layer list, and produce the canonical output.

Reference: https://github.com/opencontainers/image-spec/blob/main/manifest.md

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…