logo

Cheatsheet - Skopeo

Skopeo is a command-line utility for working with container images and image registries. It allows you to inspect, copy, delete, and sign/verify images without needing a full Docker daemon. It supports various image sources and destinations, including Docker daemon, registries, local directories, and tar archives.

What does "Skopeo" mean?

"Skopeo" can refer to the ancient Greek word skopeō, meaning "to look at" or "to contemplate," which is the root for English words like "scope".

Core Concepts

Image Reference: Skopeo uses a specific syntax to refer to images based on their location.

  • docker://registry/repository:tag: A remote Docker registry (e.g., docker.io/library/ubuntu:latest).
  • docker-daemon:image:tag: An image stored in the local Docker daemon.
  • oci:path:tag: An OCI layout directory (e.g., oci:./myimage:latest).
  • dir:path: An image stored as an unpacked filesystem in a local directory.
  • containers-storage:image:tag: An image stored in the local containers-storage (used by Podman, Buildah).
  • atomic:registry/repository:tag: An image in an Atomic Registry (often used for specific Red Hat images).
  • tarball:path: An image stored as a tarball.

Getting Started

1. Inspect an Image

  • Purpose: View detailed metadata about an image without pulling it locally.
  • Syntax:
    skopeo inspect [options] <image_reference>
    
  • Examples:
    skopeo inspect docker://docker.io/library/alpine:latest
    skopeo inspect docker://registry.access.redhat.com/ubi8/ubi-minimal:latest
    skopeo inspect docker-daemon:my-local-image:v1.0
    
  • Options:
    • --format json: Output in JSON format (default).
    • --raw: Output the raw manifest JSON.

2. Copy an Image

  • Purpose: Transfer an image between different locations (registries, local storage, tar files, etc.). This is Skopeo's most powerful feature.

  • Syntax:

    skopeo copy [options] <source_image_reference> <destination_image_reference>
    
  • Examples:

    # Copy from one remote registry to another
    skopeo copy docker://docker.io/library/alpine:latest docker://myregistry.com/myuser/alpine:latest
    
    # Copy from Docker Hub to local containers-storage (for Podman/Buildah)
    skopeo copy docker://docker.io/library/ubuntu:22.04 containers-storage:localhost/ubuntu:22.04
    
    # Copy from local Docker daemon to a remote registry
    skopeo copy docker-daemon:my-app:v1.0 docker://myregistry.com/myuser/my-app:v1.0
    
    # Export an image to a tarball
    skopeo copy docker://docker.io/library/nginx:stable-alpine tarball:nginx-stable-alpine.tar
    
    # Import an image from a tarball to local containers-storage
    skopeo copy tarball:my-app.tar containers-storage:localhost/my-app:v1.0
    
    # Copy from a remote registry to a local OCI layout directory
    skopeo copy docker://docker.io/library/hello-world:latest oci:./hello-world-oci:latest
    
  • Authentication:

    • --src-creds <username>:<password>: Credentials for the source.
    • --dest-creds <username>:<password>: Credentials for the destination.
    • --src-tls-verify=false: Disable TLS verification for source.
    • --dest-tls-verify=false: Disable TLS verification for destination.
    • --src-cert-dir <path>: Directory containing TLS client certificates for source.
    • --dest-cert-dir <path>: Directory containing TLS client certificates for destination.
    • --src-insecure-policy, --dest-insecure-policy: Allow pushing/pulling to insecure registries.
  • Other Options:

    • --all: Copy all images (including manifest lists/indexes) from source to destination.
    • --override-arch <architecture>: Override the architecture of the image.
    • --override-os <operating_system>: Override the operating system of the image.
    • --remove-signatures: Remove any existing signatures from the image when copying.

3. Delete an Image

  • Purpose: Remove an image from a remote registry or local storage.
  • Syntax:
    skopeo delete [options] <image_reference>
    
  • Examples:
    skopeo delete docker://myregistry.com/myuser/old-app:v1.0
    skopeo delete --force containers-storage:localhost/test-image:latest
    
  • Options:
    • --force: Force the deletion (useful for local storage).
    • Authentication options are similar to skopeo copy.

4. Login to a Registry

  • Purpose: Authenticate with a remote registry to push or pull images without repeatedly providing credentials.
  • Syntax:
    skopeo login <registry_url>
    skopeo login <registry_url> -u <username> -p <password>
    
  • Example:
    skopeo login docker.io -u myusername # Will prompt for password
    skopeo login quay.io -u myuser -p mypassword
    
  • Note: Credentials are saved to ~/.config/containers/auth.json (or ~/.docker/config.json).

5. Logout from a Registry

  • Purpose: Remove stored credentials for a registry.
  • Syntax:
    skopeo logout <registry_url>
    
  • Example:
    skopeo logout docker.io
    

Advanced Usage (Signing and Verification)

Skopeo integrates with container image signing and verification using gpg or a dedicated signature service.

1. Sign an Image

  • Purpose: Add a digital signature to an image manifest.

  • Syntax:

    skopeo standalone-sign [options] <image_manifest> <docker_reference> <key_id>
    
  • Example: (Requires a manifest file and GPG key)

    # 1. Pull the raw manifest
    skopeo inspect --raw docker://docker.io/library/alpine:latest > alpine_manifest.json
    
    # 2. Sign the manifest (replace with your GPG key ID)
    skopeo standalone-sign alpine_manifest.json docker.io/library/alpine:latest 0xYOURGPGKEYID
    
    # 3. Push the signature to a signature storage (e.g., a simple web server or a specific registry endpoint)
    # This often involves separate tooling or a specific registry setup like Notary.
    # For local storage, signatures are often stored in /var/lib/containers/sigstore/
    
  • Key Options:

    • --output <path>: Write the signature to a file.
    • --sign-by <key_id>: The GPG key to sign with.

2. Verify an Image Signature

  • Purpose: Check if an image's signature is valid against a trusted public key.
  • Syntax:
    skopeo standalone-verify [options] <image_manifest_file> <docker_reference> <signature_file> [<public_key_file>...]
    
  • Example: (Requires a manifest, signature, and public key)
    # Assuming you have alpine_manifest.json, alpine_signature.json, and my_public_key.gpg
    skopeo standalone-verify alpine_manifest.json docker.io/library/alpine:latest alpine_signature.json my_public_key.gpg
    
  • Tip: For automated verification, Skopeo uses policy.json files to define trust.

containers-storage and policy.json

  • containers-storage: This is the default storage backend for Podman and Buildah. Skopeo can directly interact with images stored here.
  • policy.json: Located at /etc/containers/policy.json (or ~/.config/containers/policy.json for rootless), this file defines security policies for how images can be pulled, pushed, and verified.
    • You can set rules for different registries, including whether they require signatures or can be trusted as insecure.
    • Understanding policy.json is crucial for production environments.