Container image distribution

Distribute OCI image layers and bundles as content-addressed snapshots: deduplicate shared base layers across images, replicate them between registries or regions with snapdir sync, and verify every pull.

The problem

Moving container images between environments — an air-gapped region, a second registry for redundancy, an edge fleet — is heavier than it should be. Registries re-store base layers that dozens of images share, mirroring tooling re-transfers layers the destination already has, and exporting a bundle to ship out-of-band gives you a tarball with no built-in integrity guarantee. When the same base image underpins your whole fleet, paying for and re-shipping it per image and per registry is pure waste.

Why snapdir

An OCI layout or an exported image bundle is just a directory tree, and snapdir treats it as a content-addressed snapshot:

  • Layer-level dedup. Layers are files with stable content; stored at content-addressed keys, a base layer shared by many images is stored exactly once per store.

  • Registry-to-registry replication. snapdir sync streams a bundle straight from one store to another and skips layers the destination already has — re-syncing after a rebuild copies only the new layers.

  • Verified delivery. Every layer is re-hashed on pull, so an image that lands in a remote or air-gapped environment is provably the one you exported.

Walkthrough

Export an image to an OCI layout directory (for example with skopeo copy docker://… oci:./oci-bundle:app), then snapshot the bundle to a store and capture its ID:

bundle_id=$(snapdir push --store s3://images/oci ./oci-bundle)
echo "$bundle_id"

Replicate it to a second registry's backing store without staging it locally; shared base layers already present at the destination are skipped:

snapdir sync --id "$bundle_id" --from s3://images/oci --to gs://images-eu/oci

In the target environment, pull the bundle by ID — every layer is re-hashed against the manifest as it arrives — then load it into the local registry:

snapdir pull --store gs://images-eu/oci --id "$bundle_id" ./oci-bundle
# ... skopeo copy oci:./oci-bundle:app docker://registry.internal/app ...

For an air-gapped hand-off, verify the bundle against its store before it crosses the boundary:

snapdir verify --store s3://images/oci --id "$bundle_id"

Outcome

Container images move between registries and regions as deduplicated, content-addressed snapshots: shared base layers are stored and transferred once, replication copies only what changed, and every delivery is integrity-verified on pull. The result is faster, cheaper image distribution with a cryptographic guarantee that the bundle which arrives is byte-for-byte the one that left. Track which bundles each registry holds with snapdir revisions.