skopeo Move container images

Version 1.24 · source

Start here

skopeo inspect docker://<image>
Look without pulling
skopeo list-tags docker://<repo>
List a repo's tags
skopeo copy docker://<src> docker://<dst>
Registry to registry
skopeo copy docker://<image> dir:<path>
Save to a directory
skopeo sync --src docker --dest docker <src> <dst>
Mirror a repo
skopeo login <registry>
Store credentials
skopeo delete docker://<image>
Mark for deletion
skopeo copy --all <src> <dst>
Keep all architectures

Concepts

  1. Source docker:// dir: oci:
  2. skopeo no daemon, no root
  3. Destination docker:// dir: oci-archive:
copy moves manifest, layers and signatures between any two transports
Transports (image name prefixes)
Prefix Points at
docker://<ref> Registry (Docker Registry API v2)
dir:<path> Directory of manifest and layer files
oci:<path>:<tag> OCI image layout directory
oci-archive:<path>:<tag> Tar of an OCI layout
docker-archive:<path> Tar made by docker save
docker-daemon:<ref> Local Docker daemon (needs tag)
containers-storage:<ref> Podman/Buildah local storage

Inspect & list

skopeo inspect docker://<image>
Show manifest summary without pulling
skopeo list-tags docker://<repo>
List tags in a repository
skopeo inspect --config docker://<image>
Show the image config (env, cmd, arch)
skopeo inspect --raw docker://<image>
Print the raw manifest
For a multi-arch image this is the manifest list, which shows every platform.
skopeo inspect --format '{{ .Digest }}' docker://<image>
Pick one field with a Go template
skopeo inspect --no-tags docker://<image>
Leave out the long tag list

Copy

skopeo copy <src> <dst>
Copy an image between transports
skopeo copy docker://<image> dir:<path>
Download layers to a directory
skopeo copy docker://<image> oci:<path>:<tag>
Save as OCI layout
skopeo copy docker://<image> docker-archive:<file>:<ref>
Save as a docker save tarball
skopeo copy --all <src> <dst>
Copy every platform plus the list
skopeo copy --multi-arch=<system|all|index-only|list> <src> <dst>
Choose which platforms to copy
skopeo copy --format <oci|v2s1|v2s2> <src> <dst>
Convert manifest type
skopeo copy --digestfile <file> <src> <dst>
Write resulting digest to a file
skopeo copy --retry-times <n> --retry-delay <t> <src> <dst>
Retry flaky transfers

Sync & delete

skopeo sync --src docker --dest docker <src> <dst>
Mirror all tags of a repo
skopeo sync --src docker --dest dir <repo> <dir>
Registry to local directory
skopeo sync --src dir --dest docker <dir> <registry>
Local directory to registry
skopeo sync --src yaml --dest docker <file.yml> <dst>
Sync what a YAML file lists
skopeo sync --all --src docker --dest docker <src> <dst>
Include every platform
skopeo sync --dry-run --src docker --dest docker <src> <dst>
Preview without copying
skopeo delete docker://<image>
Mark an image for deletion
Only marks the image: the registry's own garbage collector frees the space, and the registry must allow deletes.

Auth & TLS

skopeo login <registry>
Log in and store credentials
skopeo logout <registry>
Remove stored credentials
skopeo login -u <user> --password-stdin <registry>
Log in with password from stdin
Prefer this over -p, which leaves the password in shell history.
skopeo inspect --creds <user>:<pass> docker://<image>
One-off credentials
skopeo inspect --authfile <file> docker://<image>
Use a specific auth file
skopeo copy --src-creds <u:p> --dest-creds <u:p> <src> <dst>
Separate credentials per side
skopeo copy --dest-tls-verify=false <src> <dst>
Allow plain HTTP or bad certs

Platform & policy

skopeo --override-arch <arch> inspect docker://<image>
Look at another architecture
skopeo --debug copy <src> <dst>
Verbose debug output
skopeo --insecure-policy copy <src> <dst>
Skip the policy.json check
skopeo copy --sign-by <key-id> <src> <dst>
Sign with a GPG key while copying
skopeo --require-signed copy <src> <dst>
Refuse unsigned images

Recipes

Mirror one tag between registries
skopeo login registry-a.example.comskopeo login registry-b.example.comskopeo copy --all \  docker://registry-a.example.com/app:1.0 \  docker://registry-b.example.com/app:1.0
Air-gapped transfer via a directory
skopeo sync --src docker --dest dir \  registry.example.com/app /media/usb# on the offline sideskopeo sync --src dir --dest docker \  /media/usb/app my-registry.lan/