Skip to content
Registry Pull Protocol
step 1/5

Reading — step 1 of 5

Read

~1 min readFilesystems & Images

Registry Pull Protocol

docker pull alpine:3.19 is not a single request — it's an HTTP dance against the OCI Distribution Spec API (formerly Docker Registry HTTP API v2):

  1. GET /v2/library/alpine/manifests/3.19 — returns the manifest (JSON)
  2. For each layer digest in the manifest:
    • Check the local content store (/var/lib/containerd/... for containerd). If the digest is already there, skip.
    • Otherwise GET /v2/library/alpine/blobs/sha256:... and stream the bytes to disk.
  3. Once all layers are present, the image is ready.

This is why pulling alpine:3.19 a second time is instant: every blob is cached. It's also why two images that share a base layer (debian:bookworm and python:3.11-slim both base on debian) only download the base once.

Caching is per-digest, not per-tag

Tags are mutable pointers; digests are immutable. alpine:latest today and alpine:latest tomorrow may resolve to different manifest digests. The blobs themselves never change — once sha256:abc... is in your store, it's sha256:abc... forever.

What can go wrong

  • Manifest 404 (typo in repo name, untagged image) — pull fails.
  • Blob 404 (registry corruption, partial garbage collection) — pull fails mid-stream; partial layers are discarded.
  • Auth challenge (401 with WWW-Authenticate: Bearer realm=...) — the client fetches a token from the auth realm then retries. (We skip auth in this exercise.)

For this exercise: simulate the protocol — emit the requests, handle the cache, fail on missing blobs.

Discussion

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

Sign in to post a comment or reply.

Loading…