Podman and Skopeo are your go-to tools for interacting with container images, whether you’re building them, running them, or just need to poke around inside. They offer a lot of power, but sometimes their output can be a bit opaque. Let’s break down how to get the most out of podman inspect and skopeo copy.

Inspecting Container Images with podman inspect

podman inspect is your X-ray for container images and containers. It dumps a massive JSON blob detailing everything about an image, from its layers and entrypoint to environment variables and exposed ports.

Here’s a common scenario: you’ve pulled an image, say docker.io/library/alpine:latest, and you want to know exactly what command it runs by default and what ports it exposes.

podman inspect docker.io/library/alpine:latest

This will output a huge JSON array. To quickly find the entrypoint and exposed ports, you can use jq (a command-line JSON processor):

podman inspect docker.io/library/alpine:latest | jq '.[0].Config.Entrypoint'
podman inspect docker.io/library/alpine:latest | jq '.[0].Config.ExposedPorts'

The .[0] is crucial because podman inspect returns an array, even if you’re inspecting a single image. The Config object within that array holds most of the image’s metadata.

What’s actually happening? Podman, when it pulls an image, downloads its manifest and layer data. The inspect command reads this metadata, which is stored in a format defined by the OCI (Open Container Initiative) Image Specification, and presents it in a human-readable (or at least machine-parseable) JSON format. The Config section is essentially a flattened representation of the image’s configuration layers, which dictates how the image should run.

Copying Container Images with skopeo copy

skopeo copy is a fantastic tool for moving container images between different registries or even between a registry and a local directory. It doesn’t require a container runtime like Docker or Podman to be installed, making it super lightweight for CI/CD pipelines or server-side operations.

Let’s say you have an image in Docker Hub (docker.io/library/nginx:latest) and you want to copy it to a private Quay.io repository (quay.io/your-namespace/nginx:v1.21.0).

First, ensure you’re logged into both registries if they are private. For public registries, this step is usually not needed.

skopeo copy docker://docker.io/library/nginx:latest docker://quay.io/your-namespace/nginx:v1.21.0

What’s actually happening? Skopeo interacts directly with the registry APIs. When you copy, it first inspects the source image to get its manifest and layer digest information. Then, it pulls the actual layer data from the source registry. Finally, it pushes those layers and the new manifest to the destination registry, creating a new image reference. This process is layer-aware, meaning if a layer already exists in the destination, Skopeo can often skip pushing it, making subsequent copies faster.

The Surprising Power of skopeo copy --all

The most surprising thing about skopeo copy is its ability to copy all architectures and variants of an image with a single command. Most of the time, when you specify an image tag like alpine:latest, you’re implicitly getting the image for your current architecture. But an image can contain manifests for amd64, arm64, ppc64le, and more, along with different OS variants.

Consider copying docker.io/library/ubuntu:22.04 to your private registry. Without --all, you’d get the version for your machine’s architecture.

# This copies only the image for your current architecture
skopeo copy docker://docker.io/library/ubuntu:22.04 docker://my.private.registry/ubuntu:22.04

Now, let’s say you want to ensure all architectures are available in your private registry for maximum compatibility.

# This copies all architectures and OS variants
skopeo copy --all docker://docker.io/library/ubuntu:22.04 docker://my.private.registry/ubuntu:22.04

When you run skopeo copy --all, Skopeo fetches the top-level manifest list (also known as a "fat manifest" or "multi-arch manifest"). This list points to individual manifests for each architecture and OS. Skopeo then iterates through this list, pulling and pushing each architecture-specific image. This is incredibly useful for creating a comprehensive image repository that caters to diverse deployment environments without manual intervention.

Advanced skopeo copy and podman inspect Interplay

You can use skopeo to copy an image from a remote registry directly into your local Podman image storage. This bypasses the need for podman pull and can be faster if you’re just transferring an image for local use.

# Copy from Docker Hub to your local Podman storage
skopeo copy docker://docker.io/library/redis:latest docker-daemon:redis:latest

Now, if you podman images, you’ll see redis:latest listed. You can then podman inspect redis:latest to see its details, just as if you had pulled it.

The real magic comes when you want to inspect an image without pulling it first. skopeo inspect does exactly this, directly querying the registry.

skopeo inspect docker://docker.io/library/python:3.10-slim

This command fetches the image manifest and configuration directly from Docker Hub without downloading any image layers. The output is similar to podman inspect, but it’s a snapshot of the image as it exists in the registry. This is invaluable for understanding image contents or checking compatibility before committing to a download.

If you then decide you want to pull that image into Podman, you can use the information you just inspected. For example, if you saw a specific digest (sha256:...) that you wanted to ensure you got, you could use that:

podman pull docker.io/library/python@sha256:abcdef123456...

This ensures you’re pulling the exact, immutable version of the image that skopeo inspect showed you, preventing any potential tag-related surprises if the tag were updated later.

Understanding the interplay between podman inspect (for local images/containers) and skopeo inspect (for remote images) and leveraging skopeo copy for efficient transfers will significantly streamline your container workflow. The next step often involves building on these images, which brings you to tools like podman build or more advanced skopeo operations like skopeo delete.

Want structured learning?

Take the full Podman course →