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 syncstreams 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.