Skip to content
Latchkey

skopeo copy: Move Images Between Registries

skopeo copy moves a container image from one location to another without needing a Docker daemon.

skopeo works directly with registries and image transports, so it can mirror or promote images in CI without pulling them into a local daemon. copy is its most-used command.

What it does

skopeo copy transfers an image between two transports, each named with a prefix such as docker:// (a registry), oci: (an OCI layout), or dir: (a directory). It streams layers between source and destination, optionally copying every architecture in a manifest list with --all.

Common usage

Terminal
skopeo copy docker://docker.io/library/alpine:3.19 \
  docker://ghcr.io/org/alpine:3.19
# copy a full multi-arch manifest list
skopeo copy --all docker://src/app:ci docker://dst/app:ci
# with per-registry credentials
skopeo copy --dest-creds "$USER:$TOKEN" \
  docker://src/app:ci docker://ghcr.io/org/app:ci

Options

FlagWhat it does
--allCopy every image in a manifest list (multi-arch)
--src-creds / --dest-credsuser:password for each side
--dest-tls-verify=falseDisable TLS verification on the destination
--format oci|v2s2Output manifest format
--retry-times <n>Retry transient transport failures

In CI

Use skopeo copy to promote an image between registries (for example dev to prod) without a daemon, which suits rootless and ephemeral runners. Add --all so multi-arch images are copied whole, and --retry-times to ride out flaky registry connections.

Common errors in CI

"unauthorized: authentication required" means missing or wrong creds; use --src-creds/--dest-creds or skopeo login. "manifest unknown" means the source tag does not exist. "x509: certificate signed by unknown authority" on an internal registry needs the CA in the trust store or, for testing only, --dest-tls-verify=false.

Related guides

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