skopeo sync: Mirror Many Images at Once
skopeo sync copies multiple images (a whole repo, filtered tags, or a YAML manifest of images) from one location to another in a single command.
When you need to mirror a set of upstream images into an internal registry, running skopeo copy per tag is tedious. skopeo sync handles the whole set, including a declarative YAML source.
What it does
skopeo sync copies images between a source and destination whose transports are given with --src and --dest. Sources can be a docker registry repo, a local dir, or a yaml file listing images and tags. It is built for bulk mirroring rather than a single reference.
Common usage
# mirror every tag of a repo
skopeo sync --src docker --dest docker \
docker.io/library/redis ghcr.io/acme/mirror
# mirror from a YAML list of images and tags
skopeo sync --src yaml --dest docker images.yaml ghcr.io/acme/mirror
# keep source repo path under the destination
skopeo sync --src docker --dest docker --scoped \
registry.example.com/team ghcr.io/acme/mirrorOptions
| Flag | What it does |
|---|---|
| --src <transport> | Source transport: docker, dir, or yaml |
| --dest <transport> | Destination transport: docker or dir |
| --scoped | Prefix copied images with the full source path (avoids name clashes) |
| --all | Copy all architectures of each image |
| --src-creds / --dest-creds | Credentials per side |
| --dest-tls-verify=false | Skip TLS on the destination |
In CI
Store the set of images to mirror as a yaml source in the repo, then run one skopeo sync in a scheduled job. This mirrors upstream images into an internal registry so builds never depend on a rate-limited public registry at runtime.
Common errors in CI
"unauthorized: authentication required" on the source needs --src-creds; on the destination --dest-creds. "toomanyrequests: You have reached your pull rate limit" from Docker Hub means authenticate the source or mirror less often. A yaml source that copies nothing usually has an indentation or tag-filter mistake; validate the file. Name collisions on the destination are solved with --scoped.