Registries

Skopeo

CLI Red Hat pour opérations sur images OCI sans Docker daemon. Copie entre registries, inspection de manifests sans pull, synchronisation de dépôts, suppression distante. Projet containers/.

Skopeo est un outil en ligne de commande pour effectuer des opérations sur des images et des registries de conteneurs sans avoir besoin du daemon Docker, ni de root. Développé par Red Hat dans le cadre du projet containers/, il fait partie de la même famille que Podman et Buildah.

Sa commande principale est skopeo copy : elle copie une image d'une source vers une destination en supportant des dizaines de combinaisons de transports (docker://, oci://, docker-archive://, dir://...). C'est l'outil de référence pour les migrations air-gapped, la synchronisation inter-registries et l'inspection de manifests en CI/CD.

Idéal pour : copier des images entre registries sans les télécharger sur le disque local, synchroniser des registries en air-gapped, inspecter des manifests d'images sans docker pull, supprimer des tags depuis un registry.


Informations essentielles

Origine : Red Hat / projet containers/  ·  Licence : Apache 2.0  ·  Architectures : x86_64, ARM64, ppc64le, s390x

Liens : GitHub  ·  Documentation  ·  Releases

Support : Maintenu activement par Red Hat. Intégré dans RHEL/Fedora. Releases régulières.

Transports supportés

TransportDescription
docker://Registry distant (Docker Hub, Harbor, ECR...)
oci://Dossier au format OCI Image Layout
docker-archive://Fichier tar au format Docker (docker save/load)
oci-archive://Fichier tar au format OCI
docker-daemon://Daemon Docker local
containers-storage://Storage Podman/Buildah local
dir://Dossier en format natif Skopeo

Installation

RHEL / Rocky Linux / Fedora

sudo dnf install -y skopeo
skopeo --version

Ubuntu / Debian

sudo apt-get install -y skopeo
skopeo --version

Binaires officiels

# Via le dépôt Kubic
. /etc/os-release
echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/ /" \
  | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
sudo apt-get update && sudo apt-get install -y skopeo

Copier des images

skopeo copy est la commande centrale. Elle ne télécharge pas l'image localement - elle la transfère directement de source à destination layer par layer.

# Docker Hub -> registry privé
skopeo copy \
  docker://nginx:alpine \
  docker://registry.example.com/mirror/nginx:alpine

# Avec authentification
skopeo copy \
  --src-creds=user:password \
  --dest-creds=user:password \
  docker://source-registry.example.com/mon-app:1.0 \
  docker://dest-registry.example.com/mon-app:1.0

# Registry -> fichier tar Docker (pour transport physique)
skopeo copy \
  docker://nginx:alpine \
  docker-archive:///tmp/nginx-alpine.tar

# Fichier tar -> registry (import air-gapped)
skopeo copy \
  docker-archive:///tmp/nginx-alpine.tar \
  docker://registry.example.com/nginx:alpine

# Registry -> dossier OCI
skopeo copy \
  docker://nginx:alpine \
  oci:///data/nginx-oci:alpine

Copie multi-architecture

# Copier tous les manifests (multi-arch) en préservant l'index OCI
skopeo copy --all \
  docker://nginx:alpine \
  docker://registry.example.com/nginx:alpine

# Sans --all, seule l'image de l'architecture courante est copiée

Inspecter sans télécharger

skopeo inspect récupère le manifest et les métadonnées d'une image sans télécharger les layers.

# Inspecter depuis Docker Hub
skopeo inspect docker://nginx:alpine

# Output JSON incluant :
# - Architecture, OS
# - Labels
# - Variables d'environnement
# - Layers (digests SHA256)
# - Digest de l'image

# Afficher uniquement le digest
skopeo inspect docker://nginx:alpine | jq '.Digest'

# Inspecter le manifest brut (format OCI)
skopeo inspect --raw docker://nginx:alpine | jq .

# Inspecter une image multi-arch (l'index)
skopeo inspect --raw docker://nginx:alpine | jq '.manifests[] | {platform, digest}'

Synchronisation de dépôts

skopeo sync copie un dépôt entier (ou une liste d'images) vers une destination.

# Synchroniser un dépôt entier
skopeo sync \
  --src docker \
  --dest docker \
  registry-source.example.com/mon-projet \
  registry-dest.example.com/mon-projet

# Synchroniser depuis un fichier de liste (YAML)
# images.yaml :
# registry-source.example.com:
#   images:
#     nginx: ["alpine", "1.25"]
#     redis: ["7-alpine"]

skopeo sync \
  --src yaml \
  --dest docker \
  images.yaml \
  registry-dest.example.com

Fichier de liste pour air-gapped

# images.yaml
registry-1.docker.io:
  images:
    library/nginx:
      - "alpine"
      - "1.25-alpine"
    library/postgres:
      - "16-alpine"
ghcr.io:
  images:
    cert-manager/cert-manager-controller:
      - "v1.14.0"
# Sync vers un dossier local (pour clé USB / transport physique)
skopeo sync \
  --src yaml \
  --dest dir \
  images.yaml \
  /media/usb/images/

# Puis importer depuis le dossier sur le réseau isolé
skopeo sync \
  --src dir \
  --dest docker \
  /media/usb/images/registry-1.docker.io \
  registry.interne.example.com

Lister les tags

# Lister tous les tags d'une image
skopeo list-tags docker://nginx
skopeo list-tags docker://registry.example.com/mon-app

# Avec authentification
skopeo list-tags \
  --creds=user:password \
  docker://registry.example.com/mon-app

Supprimer des images

# Supprimer un tag depuis un registry
skopeo delete docker://registry.example.com/mon-app:old-tag

# Avec authentification
skopeo delete \
  --creds=user:password \
  docker://registry.example.com/mon-app:old-tag

# Note : certains registries nécessitent que la suppression par digest soit activée
# (distribution: storage.delete.enabled: true)

Authentification

Fichier de credentials (recommandé en CI/CD)

# Skopeo lit ~/.docker/config.json automatiquement après docker login
docker login registry.example.com

# Ou spécifier un fichier de credentials différent
skopeo --authfile /path/to/auth.json copy ...

# Format du fichier auth.json
{
  "auths": {
    "registry.example.com": {
      "auth": "<base64(user:password)>"
    }
  }
}

Variables d'environnement (CI/CD)

# Inline dans la commande
skopeo copy \
  --src-creds="${SRC_USER}:${SRC_PASSWORD}" \
  --dest-creds="${DEST_USER}:${DEST_PASSWORD}" \
  docker://source/image:tag \
  docker://dest/image:tag

Utilisation en CI/CD

Promotion d'image entre environnements

# Promouvoir une image de staging vers production (sans rebuilder)
skopeo copy \
  --src-creds="${STAGING_USER}:${STAGING_PASS}" \
  --dest-creds="${PROD_USER}:${PROD_PASS}" \
  docker://staging-registry.example.com/mon-app:${CI_COMMIT_SHA} \
  docker://prod-registry.example.com/mon-app:${VERSION}

Vérifier qu'une image existe avant déploiement

if skopeo inspect docker://registry.example.com/mon-app:${VERSION} > /dev/null 2>&1; then
  echo "Image existe - déploiement possible"
else
  echo "Image manquante - build requis"
  exit 1
fi

Mise à jour

# RHEL / Rocky / Fedora
sudo dnf update skopeo

# Ubuntu / Debian
sudo apt-get install --only-upgrade skopeo

skopeo --version

Commandes utiles

# Copier
skopeo copy docker://source:tag docker://dest:tag
skopeo copy --all docker://source:tag docker://dest:tag  # multi-arch

# Inspecter
skopeo inspect docker://image:tag
skopeo inspect --raw docker://image:tag | jq .

# Lister
skopeo list-tags docker://image

# Supprimer
skopeo delete docker://registry/image:tag

# Synchroniser
skopeo sync --src docker --dest docker source-registry/repo dest-registry
skopeo sync --src yaml --dest dir images.yaml /data/

Ressources

Newsletter · 2 000+ abonnés

Reste au courant de ce qui bouge en prod

RudeOps veille devops hebdo, droit au but.

Gratuit · Sans spam · Désinscription en un clic