# 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](../concepts/content-addressing.md) keys, a base layer shared by many images is stored exactly once per store. - **Registry-to-registry replication.** [`snapdir sync`](../guide/syncing.md) 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](../concepts/integrity.md), 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: ```sh 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: ```sh 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: ```sh 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: ```sh 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`](../guide/history.md).