Skopeo is a command-line tool for working with container images and container image registries without requiring a running container daemon or root privileges. While Docker requires docker pull to download an image locally before inspecting or copying it, Skopeo can copy images directly between registries, inspect image metadata without downloading the full image, and sign/verify images — all without ever writing layers to disk. Skopeo understands multiple image formats: Docker registry format, OCI (Open Container Initiative) format, and dir (local directory). It is part of the container tools suite maintained by Red Hat and ships with RHEL 9. Common use cases include: mirroring images between registries for air-gapped environments, inspecting images in production registries without pulling them, and converting images between formats.
Prerequisites
- RHEL 9 with sudo access (Skopeo can run as a non-root user)
Step 1 — Install Skopeo
# Available in RHEL 9 AppStream
dnf install -y skopeo
skopeo --version
Step 2 — Inspect Images Without Pulling
# Inspect image metadata from a public registry (no docker pull needed)
skopeo inspect docker://nginx:alpine
# Get available tags for an image
skopeo list-tags docker://nginx
# Inspect a private registry (with credentials)
skopeo inspect --creds username:password docker://registry.example.com/myapp:latest
# Show just the labels
skopeo inspect docker://nginx:alpine | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['Labels'])"
Step 3 — Copy Images Between Registries
# Mirror an image from Docker Hub to a private registry
# (No 'docker pull' + 'docker push' needed — direct registry-to-registry transfer)
skopeo copy
docker://nginx:alpine
docker://registry.example.com/nginx:alpine
--dest-creds username:password
# Copy all tags for an image
skopeo copy --all
docker://nginx
docker://registry.example.com/nginx
# Copy to OCI format (for air-gapped environments)
skopeo copy docker://nginx:alpine oci:/tmp/nginx-oci:alpine
# Copy from OCI to a registry
skopeo copy oci:/tmp/nginx-oci:alpine docker://registry.example.com/nginx:alpine
Step 4 — Mirror Images for Air-Gapped Clusters
# Save multiple images to a directory for offline transport
mkdir /tmp/k8s-images
for image in nginx:alpine redis:7-alpine postgres:16-alpine; do
name=$(echo $image | tr '/:' '_')
skopeo copy docker://$image dir:/tmp/k8s-images/$name
echo "Saved $image"
done
# Transfer /tmp/k8s-images to air-gapped server, then restore:
for dir in /tmp/k8s-images/*/; do
name=$(basename $dir)
image=$(echo $name | tr '_' '/')
skopeo copy dir:$dir docker://internal-registry.local/$image
done
Step 5 — Delete Images from a Registry
# Delete an image from a private registry
skopeo delete
docker://registry.example.com/myapp:old-tag
--creds username:password
# Sync an entire repository (Skopeo 1.3+)
skopeo sync
--src docker
--dest docker
--src-creds srcuser:srcpass
--dest-creds destuser:destpass
nginx registry.example.com/mirror
Conclusion
Skopeo on RHEL 9 is the most efficient tool for container image management tasks that would otherwise require a Docker daemon. The direct registry-to-registry copy capability (skopeo copy docker://source docker://dest) eliminates the intermediate “pull to local disk then push” workflow, significantly reducing bandwidth and storage usage when mirroring images for Kubernetes clusters or air-gapped environments. Combined with Podman and Buildah, Skopeo forms the Red Hat container tools trifecta: Buildah builds images, Podman runs them, and Skopeo moves them between registries.
Next steps: How to Install Podman on RHEL 9, How to Set Up a Private Docker Registry on RHEL 9, and How to Configure Docker Daemon TLS on RHEL 9.