Give it a quick spin
Have you ever been frustrated waiting 15 minutes just to pull a 3GB image, re-tag it, and then push it to another registry? If so, Skopeo is your lifesaver.
Installing Skopeo on Ubuntu/Debian takes only a few seconds:
sudo apt-get update
sudo apt-get install -y skopeo
Suppose you need to move the nginx:latest image from Docker Hub to a private registry without downloading it to your local machine. Use this command:
skopeo copy \
docker://docker.io/library/nginx:latest \
docker://registry.mycompany.com/production/nginx:latest
In this case, Skopeo acts as a “broker,” coordinating data directly between the two registries via API. You don’t need Docker Engine, you don’t need sudo privileges, and most importantly, your disk remains empty.
Why should you ditch the Pull -> Tag -> Push workflow?
The traditional method typically causes three extremely frustrating issues for DevOps engineers:
- Bandwidth consumption: Downloading 2GB of data and then uploading it back to another server is a massive waste of resources. If the network is slow, you could spend all morning just copying a few images.
- Disk space exhaustion: Docker’s intermediate layers often take up significant space. On CI/CD runners with limited disk space (around 20GB), pulling heavy images will cause the pipeline to crash immediately.
- Docker Daemon dependency: Not every environment has Docker pre-installed. In modern systems like Kubernetes, running Docker-inside-Docker often poses security risks.
Skopeo solves these problems completely. It communicates directly with the registry via HTTP API to manipulate manifests and layers without extracting anything to your machine.
Most practical features
1. Inspect: Peek into Image content in 1 second
Want to know if an image supports arm64 or amd64 before downloading? Instead of pulling it to check, use the inspect command:
skopeo inspect docker://docker.io/library/ubuntu:22.04
The result is a detailed JSON object containing tags, layers, and architecture. Pro tip: JSON output in the terminal can be hard to read. I usually copy it and paste it into the JSON formatter at toolcraft.app/en/tools/developer/json-formatter. This helps me analyze the image structure much faster than fiddling with extensions.
2. Copy: Move images anywhere
This command allows you to move images flexibly between different formats:
docker://: Transfer between standard registries.oci://: Use the Open Container Initiative format.dir://: Save the image to a directory (ideal for backups).
For example, to back up an image to an air-gapped server (no internet), you can just save it to a directory:
skopeo copy docker://alpine:latest dir:/home/dev/backup-alpine
3. Delete: Clean up remote registries
The Docker CLI doesn’t natively allow you to delete images directly from a registry. With Skopeo, if you have admin privileges, cleaning up old builds becomes effortless:
skopeo delete docker://registry.mycompany.com/old-app:v1
Handling Authentication and Private Registries
When working with systems that require authentication like AWS ECR or GitLab, you can pass credentials directly:
skopeo copy \
--src-creds source_user:source_password \
--dest-creds target_user:target_password \
docker://docker.io/myrepo/private-image:latest \
docker://quay.io/another-repo/image:latest
If you have already performed a docker login, Skopeo will automatically look for the ~/.docker/config.json file to retrieve the token. You won’t need to re-enter your password.
Batch sync with the ‘sync’ command
Imagine having to move 50 tags of a project from Docker Hub to Google Cloud. Instead of typing the command 50 times, you can just create a sync.yaml file:
'docker.io/itfromzero':
images:
nginx: ['1.21', '1.22', 'latest']
redis: ['6.2', '7.0']
Then run the sync command: skopeo sync --src yaml --dest docker sync.yaml gcr.io/my-project. In just a few minutes, your entire image repository will be “cloned” to its new home.
Real-world implementation tips
Handling SSL errors with internal registries
If you use a self-hosted registry without a valid SSL certificate, Skopeo will throw a certificate error. Don’t worry, just add the --dest-tls-verify=false flag to bypass security checks.
Optimizing for CI/CD Pipelines
In Jenkins or GitLab Runners, I always prioritize Skopeo over Docker. It keeps the Runner VM completely clean after execution. You’ll no longer face pipeline hangs due to “No space left on device” errors caused by accumulated image junk.
In summary, if you frequently manage images or switch between cloud providers, Skopeo is an indispensable tool. It’s lightweight, fast, and makes your workflow much more professional.

