Skip to content
Latchkey

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

Terminal
# 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/mirror

Options

FlagWhat it does
--src <transport>Source transport: docker, dir, or yaml
--dest <transport>Destination transport: docker or dir
--scopedPrefix copied images with the full source path (avoids name clashes)
--allCopy all architectures of each image
--src-creds / --dest-credsCredentials per side
--dest-tls-verify=falseSkip 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.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →