crane copy: Copy Images Without a Daemon
crane copy moves an image from one registry reference to another directly, with no Docker daemon.
crane, from go-containerregistry, is a fast daemonless registry tool. copy promotes or mirrors images by streaming manifests and layers between references.
What it does
crane copy (alias crane cp) reads the source manifest and copies it and its layers to the destination reference. By default it copies the whole image including all platforms in an index; --platform narrows it. It authenticates via the standard Docker config or crane auth login.
Common usage
crane copy docker.io/library/alpine:3.19 ghcr.io/org/alpine:3.19
# mirror every tag in a repository
crane copy --all-tags docker.io/library/alpine ghcr.io/org/alpine
# copy only one platform
crane copy --platform linux/amd64 src/app:ci dst/app:ciOptions
| Flag | What it does |
|---|---|
| --all-tags, -a | Copy every tag in the source repository |
| --platform <os/arch> | Copy only the named platform |
| --insecure | Allow plain HTTP / skip TLS verify (testing) |
| crane auth login | Authenticate before copying |
| --jobs <n> | Number of concurrent layer copies |
In CI
crane copy is well suited to image promotion in pipelines because it is fast and needs no daemon. Authenticate with crane auth login (or a mounted Docker config) for both registries. Use --platform to copy a single arch when you do not need the full index.
Common errors in CI
"UNAUTHORIZED" or "401 Unauthorized" means missing credentials for the source or destination; run crane auth login for each registry. "MANIFEST_UNKNOWN" means the source tag does not exist. "DENIED: requested access to the resource is denied" usually means the destination repo path is wrong or the token lacks push scope.