Skopeo

repository·main·Indexed 11 days ago

https://github.com/podman-container-tools/skopeo

A command-line utility for performing operations on container images and image repositories—such as inspecting, copying, deleting, and syncing—without requiring a daemon or root privileges. It supports multiple storage backends and transport types, including docker://, oci:, dir:, and docker-archive:. Key features include the ability to inspect remote images without pulling them, synchronize registries for air-gapped deployments via `skopeo sync`, and manage multi-architecture image copying.

Tokens
19.9K
Snippets
65
Records
94
Agent score
92%

What's inside Skopeo

  1. Understand the skopeo-experimental-image-proxy communication protocol

    main

    The proxy uses a SOCK_SEQPACKET socket for control messages and pipe(2) for large data payloads (manifests and blobs).

    Message Formats

    Request Format (JSON):

    { "method": "MethodName", "args": [arguments] }

    Reply Format (JSON):

    { "success": boolean, "value": JSONValue, "pipeid": number, "error_code": string, "error": string }
    • success: true if the call succeeded, false otherwise.
    • value: The return value of the method (e.g., an image ID or digest).
    • pipeid: An integer identifying a pipe for data transfer. This ID must be used with the FinishPipe method.
    • error_code: A string indicating the error type (e.g., EPIPE, retryable, other). Introduced in version 0.2.8.
    • error: A string describing the error.

    Data Transfer Lifecycle

    1. The client sends a request via the socket.
    2. The server replies with a JSON object containing a pipeid and the value.
    3. The server passes the read-end of a pipe via file descriptor (FD) passing.
    4. The client reads the data from the passed FD.
    5. Crucial: After consuming all data, the client must call FinishPipe with the corresponding pipeid. This allows the server to clean up and report errors (like digest mismatches) that occurred during streaming.
  2. Understand Skopeo image and repository transport types

    main

    Skopeo uses specific transport prefixes to identify the storage mechanism of an image or repository. When performing operations like copy, inspect, or delete, you must prefix your image references with one of the following:

    • containers-storage:docker-reference: An image in a local containers/storage image store (used by Podman, CRI-O, and Buildah). The location and store are defined in /etc/containers/storage.conf.
    • dir:path: A local directory containing the manifest, layer tarballs, and signatures as individual files.
    • docker://docker-reference: An image in a registry implementing the "Docker Registry HTTP API V2".
    • docker-archive:path[:docker-reference]: An image stored in a docker save-formatted file. When creating such a file, docker-reference must not contain a digest.
    • docker-daemon:docker-reference: An image stored in the Docker daemon's internal storage. For reading, you can use docker-daemon:algo:digest (an image ID).
    • oci:path:tag: An image tag in a directory compliant with the "Open Container Image Layout Specification".
  3. Available transports for skopeo sync

    main

    When using skopeo sync, you must specify the transport type for both the source and the destination.

    Source Transports (--src)

    • docker: The source is a repository hosted on a container registry (e.g., registry.example.com/busybox). If no tag is specified, all tags in the repository are copied.
    • dir: The source is a local directory path (e.g., /media/usb/).
    • yaml: The source is a local YAML file path containing a list of images to be copied.

    Destination Transports (--dest)

    • docker: The destination is a container registry (e.g., my-registry.local.lan).
    • dir: The destination is a local directory path. One directory per source image:tag is created for each copied image.
  4. Understand Skopeo image transport formats

    main

    Skopeo uses a transport:details format to reference container images. This allows you to interact with images across different storage backends without needing a container runtime. Common transports include:

    • containers-storage:docker-reference: Images in a local containers/storage store (used by Podman, CRI-O, etc.).
    • docker://docker-reference: Images in a registry implementing the Docker Registry HTTP API V2.
    • dir:path: A local directory containing manifest, layer tarballs, and signatures.
    • docker-archive:path[:docker-reference]: Images in a docker save formatted file.
    • docker-daemon:docker-reference: Images stored in the Docker daemon's internal storage.
    • oci:path:tag: Images in a directory following the OCI Layout Specification.
    • oci-archive:path:tag: Images in an OCI-compliant tar archive.
    docker://registry.example.com/my-image:latest
    containers-storage:localhost/my-image:latest
    dir:/tmp/image-layers
  5. Understand the limitations of skopeo-standalone-sign

    main

    When using skopeo standalone-sign, keep the following technical constraints in mind:

    • Signature Formats: The command is intended for use with local signatures, such as OpenPGP. Other formats may be supported in future versions.
    • Docker Content Trust (DCT): This command does not interact with artifacts generated by Docker Content Trust (DCT).
    • Workflow Recommendation: For production or standard image publishing, use skopeo copy --sign-by instead of this standalone signing tool.
  6. Configure synchronization using a YAML file

    main

    When using --src yaml, you can provide a YAML file that defines complex synchronization rules, including specific tags, regex patterns, and semantic version constraints for multiple registries.

    YAML Structure

    • images: A map of repository names to a list of specific tags or digests.
    • images-by-tag-regex: A map of repository names to regex patterns for matching tags.
    • images-by-semver: A map of repository names to semantic version constraints.
    • credentials: Registry-specific username and password.
    • tls-verify: Boolean to enable/disable TLS verification for that registry.
    • cert-dir: Path to certificates for that registry.

    Example YAML (sync.yml)

    registry.example.com:
        images:
            busybox: []
            redis:
                - "1.0"
                - "2.0"
                - "sha256:0000000000000000000000000000000011111111111111111111111111111111"
        images-by-tag-regex:
            nginx: ^1\.13\.[12]-alpine-perl$
        images-by-semver:
            alpine: ">= 3.12.0"
        credentials:
            username: john
            password: this is a secret
        tls-verify: true
        cert-dir: /home/john/certs
    quay.io:
        tls-verify: false
        images:
            coreos/etcd:
                - latest

    Running the sync

    $ skopeo sync --src yaml --dest docker sync.yml my-registry.local.lan/repo/
    skopeo sync --src yaml --dest docker sync.yml my-registry.local.lan/repo/
  7. Use the skopeo experimental-image-proxy API server

    main

    The skopeo experimental-image-proxy command is an experimental API server that provides a lightweight way to fetch container image content (manifests and blobs) via a custom JSON+fd-passing protocol. It is primarily intended for programs that need to operate on custom storage backends (e.g., the bootc project's ostree-based storage) that Skopeo does not natively handle.

    Setup and Execution

    To use the proxy, the client process must create a socketpair(2) of type SOCK_SEQPACKET. One end of the socket is passed to the proxy.

    By default, the proxy expects the socket to be provided on standard input (file descriptor 0). You can specify a different file descriptor using the --sockfd option.

    Note: This command is experimental, its API is subject to change, it is currently hidden from main help outputs, and it is not supported on Windows.

    skopeo experimental-image-proxy [--sockfd fd] [options]
  8. Generate a Sigstore public/private key pair

    main

    Use the skopeo generate-sigstore-key command to create a public/private key pair specifically designed for creating Sigstore image signatures.

    Key Output Files:

    • The private key is saved as {prefix}.private.
    • The public key is saved as {prefix}.pub.

    Security Note: The private key is encrypted with a passphrase. If you do not provide a passphrase via the --passphrase-file option, the command will prompt you to enter one interactively. Using --passphrase-file is discouraged if the file is readable by other users on the system.

    $ skopeo generate-sigstore-key --output-prefix mykey
  9. Encrypt and decrypt container images

    main

    Skopeo allows you to encrypt image layers during the copy process using a JWE (JSON Web Encryption) key.

    Encryption

    Use the --encryption-key flag followed by the jwe: prefix and the path to your public key. You can also target specific layers using --encrypt-layer with 0-indexed or negative indexing (e.g., 0 for the first layer, -1 for the last).

    Decryption

    Use the --decryption-key flag with the path to your private key. If an image requires multiple keys, you can provide multiple --decryption-key flags.

    Key Details

    • Partial Encryption: Use --encrypt-layer <index> to encrypt only a specific layer.
    • Multiple Keys: Pass --decryption-key multiple times for images requiring multiple keys.
    # Encrypt an image
    $ skopeo copy --encryption-key jwe:./public.key oci:local_nginx:1.17.8 oci:try-encrypt:encrypted
    
    # Encrypt only the 2nd layer (index 1)
    $ skopeo copy --encryption-key jwe:./public.key --encrypt-layer 1 oci:local_nginx:1.17.8 oci:try-encrypt:encrypted
    
    # Decrypt an image
    $ skopeo copy --decryption-key ./private.key oci:try-encrypt:encrypted oci:try-decrypt:decrypted
    
    # Decrypt an image requiring multiple keys
    $ skopeo copy --decryption-key ./private1.key --decryption-key ./private2.key --decryption-key ./private3.key oci:try-encrypt:encrypted oci:try-decrypt:decrypted
  10. Sync registries for air-gapped deployments

    main

    The skopeo sync command can synchronize images between registry repositories and local directories, which is useful for preparing images for air-gapped environments.

    # Sync a registry image to a local directory
    $ skopeo sync --src docker --dest dir registry.example.com/busybox /media/usb
  11. Inspect a remote image repository

    main

    The skopeo inspect command fetches a repository's manifest to provide low-level information (similar to docker inspect) without requiring you to pull the full image to your host. This allows you to view metadata like layers, labels, architecture, and creation dates while saving disk space.

    Use the --config flag to specifically view the container configuration (environment variables, entrypoints, etc.) instead of the full repository metadata.

    # Show general properties of a remote image
    $ skopeo inspect docker://registry.fedoraproject.org/fedora:latest
    
    # Show only the container configuration (JSON)
    $ skopeo inspect --config docker://registry.fedoraproject.org/fedora:latest | jq
    
    # Get only the digest of an image
    $ skopeo inspect docker://registry.fedoraproject.org/fedora:latest | jq '.Digest'
  12. Logout of a container registry with skopeo logout

    main

    Use the skopeo logout command to remove cached credentials for a specific registry from your authentication file. This command deletes the credentials stored in the auth.json file for the specified registry server.

    By default, Skopeo uses the path defined in the REGISTRY_AUTH_FILE environment variable, or ${XDG_RUNTIME_DIR}/containers/auth.json on Linux.

    $ skopeo logout docker.io