# How to Use OCI Images with Container: Pull, Run, and Manage OCI-Compliant Images

> Learn to use OCI images with Container. Discover how Container natively supports OCI artifacts for pulling, running, and managing compliant images efficiently. Get started today.

- Repository: [Apple/container](https://github.com/apple/container)
- Tags: how-to-guide
- Published: 2026-06-25

---

**Container treats OCI images as first-class artifacts by leveraging the ContainerizationOCI Swift package to normalize references, resolve platform targets, pull manifests, and unpack layers into runnable containers.**

Apple's open-source `container` tool provides native support for OCI (Open Container Initiative) images, allowing you to pull, run, and manage standards-compliant container images directly from Swift-based tooling. Whether you are working with Docker Hub or private registries, the repository handles OCI image validation, platform resolution, and layer unpacking through a modular architecture built on the **ContainerizationOCI** package.

## Understanding OCI Image Support in Container

The `container` repository delegates all OCI-specific logic to the `ContainerizationOCI` module, ensuring full compliance with the OCI Image Specification. This separation of concerns means that heavy lifting—such as reference validation, manifest handling, and blob streaming—is abstracted behind clean Swift APIs while the CLI in [`Sources/ContainerCommands/Image/ImagePull.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Image/ImagePull.swift) orchestrates user interactions.

## The OCI Image Workflow in Container

When you execute a command like `container image pull`, the tool follows a strict pipeline from reference parsing to runtime execution.

### Reference Parsing and Normalization

User-supplied image references (e.g., `docker://alpine:latest`) are first normalized by `ClientImage.normalizeReference` in [`Sources/ContainerCommands/Image/ImagePull.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Image/ImagePull.swift). This function utilizes `ContainerizationOCI.Reference` to validate the string, apply default registries, and produce a canonical form suitable for registry communication.

### Platform Resolution

The command-line options `--os`, `--arch`, and `--platform` are combined into a `ContainerizationOCI.Platform` via `DefaultPlatform.resolve`, defined in [`Sources/ContainerCommands/Image/DefaultPlatform.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Image/DefaultPlatform.swift). This step ensures that multi-architecture images are fetched for the correct CPU architecture and operating system target.

### Image Fetching from Registries

`ClientImage.pull` contacts the OCI registry using the `ContainerizationOCI` HTTP client, streaming the manifest, config, and layer blobs. Progress is reported through the `ProgressBar` infrastructure, with the implementation residing in [`Sources/ContainerCommands/Image/ImagePull.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Image/ImagePull.swift) around lines 96-100.

### Unpacking and Runtime Preparation

Once the manifest is retrieved, the `Image.unpack` method extracts the tar-formatted layer blobs onto the sandbox's rootfs. The unpacked OCI image is then represented by `ImageResource` (a thin wrapper around `ContainerizationOCI.Image`) defined in [`Sources/ContainerResource/Image/ImageResource.swift`](https://github.com/apple/container/blob/main/Sources/ContainerResource/Image/ImageResource.swift). Finally, `ContainerCLI.run` launches the container, passing the OCI config (process, environment, mounts, and capabilities) directly to the low-level runtime.

## Working with OCI Images via CLI

The following commands demonstrate practical OCI image operations using the `container` binary.

**Pull an image from Docker Hub:**

```bash
container image pull docker://alpine:latest

```

**List locally cached OCI images:**

```bash
container image list

```

**Run a container from a pulled image:**

```bash
container run \
    --image docker://alpine:latest \
    --cmd /bin/sh

```

**Save an OCI image as a tar archive:**

```bash
container image save \
    --image docker://alpine:latest \
    --output alpine.tar

```

**Push a locally built image to a private registry:**

```bash
container image push \
    --image myapp:1.0 \
    myregistry.example.com/myapp:1.0

```

## Programmatic OCI Image Handling in Swift

For developers integrating container functionality directly into Swift applications, the `ContainerAPIClient` and `ContainerizationOCI` modules provide type-safe OCI operations.

```swift
import ContainerAPIClient
import ContainerizationOCI

let systemConfig = try await Application.loadContainerSystemConfig()
let platform = try DefaultPlatform.resolve(platform: nil, os: "linux", arch: "arm64", log: nil)

let reference = try ClientImage.normalizeReference(
    "docker://nginx:latest",
    containerSystemConfig: systemConfig
)

let image = try await ClientImage.pull(
    reference: reference,
    platform: platform,
    scheme: .https,
    containerSystemConfig: systemConfig,
    progressUpdate: nil,
    maxConcurrentDownloads: 4
)

try await image.unpack(platform: platform, progressUpdate: nil)

// Run the image
let container = try await ContainerCLI.run(image: image, args: ["nginx", "-g", "daemon off;"])

```

## Summary

- **Container** treats OCI images as first-class artifacts through the `ContainerizationOCI` Swift package.
- **Reference normalization** occurs via `ClientImage.normalizeReference` in [`Sources/ContainerCommands/Image/ImagePull.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Image/ImagePull.swift), validating and canonicalizing image strings.
- **Platform resolution** uses `DefaultPlatform.resolve` to handle multi-architecture images via `--os`, `--arch`, and `--platform` flags.
- **Image fetching** streams manifests and layers through `ClientImage.pull`, while unpacking is handled by `Image.unpack` before runtime execution.
- **CLI commands** like `image pull`, `image list`, `run`, `save`, and `push` provide complete OCI lifecycle management.

## Frequently Asked Questions

### What registry protocols does container support for OCI images?

The tool supports any OCI-compliant registry using the `ContainerizationOCI` HTTP client, including Docker Hub, GitHub Container Registry, and private registries. Validation of hostnames and reference domains follows the OCI Distribution Specification, implemented in [`Sources/ContainerResource/Registry/RegistryResource.swift`](https://github.com/apple/container/blob/main/Sources/ContainerResource/Registry/RegistryResource.swift).

### How does container handle multi-platform OCI images?

Multi-platform support is resolved through `DefaultPlatform.resolve` in [`Sources/ContainerCommands/Image/DefaultPlatform.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Image/DefaultPlatform.swift), which constructs a `ContainerizationOCI.Platform` from CLI flags. This ensures the correct manifest and layer blobs are fetched for the specified operating system and CPU architecture combination.

### Can I use container with private OCI registries that require authentication?

Yes. The `ClientImage.pull` function and associated registry helpers support authentication mechanisms compliant with the OCI Distribution Specification. Credentials are typically resolved through the container system configuration loaded via `Application.loadContainerSystemConfig()`.

### Where is the OCI image stored after pulling?

After `ClientImage.pull` retrieves the manifest and layers, `Image.unpack` extracts the tar-formatted blobs onto the sandbox's rootfs. The metadata is wrapped in `ImageResource` (defined in [`Sources/ContainerResource/Image/ImageResource.swift`](https://github.com/apple/container/blob/main/Sources/ContainerResource/Image/ImageResource.swift)), which maintains the OCI config, size, and digests for local caching and runtime usage.