How apple/container Handles OCI Image Format and Registry Interactions

apple/container implements OCI image support through the external ContainerizationOCI Swift package, which models OCI specifications as type-safe structs, while registry interactions follow the OCI Distribution Specification via HTTP endpoints handled in RegistryResource.swift.

The apple/container repository is a Swift-based container runtime developed by Apple that natively supports the Open Container Initiative (OCI) image format. It handles OCI image format and interacts with registries through a layered architecture that separates data modeling, storage, and transport concerns across distinct modules.

OCI Architecture Overview

Core Data Models

All OCI-compliant operations in apple/container rely on the ContainerizationOCI package. This external dependency provides the foundational types that mirror the OCI image and distribution specifications:

  • ContainerizationOCI.Image – Represents the parsed image configuration
  • ContainerizationOCI.Manifest – Models the OCI manifest JSON structure
  • ContainerizationOCI.Platform – Encodes OS/architecture constraints
  • ContainerizationOCI.Reference – Validates and stores registry names, repositories, and tags

These types are imported throughout the codebase (e.g., import ContainerizationOCI in command and service files) to ensure type safety when handling image metadata.

Layered Implementation

The repository organizes OCI functionality into five distinct layers:

  1. OCI Model Layer – Defines index, config, manifest, and platform descriptors via the ContainerizationOCI package
  2. Registry Interaction Layer – Validates hostnames and constructs HTTP requests to OCI distribution endpoints (/v2/…) in Sources/ContainerResource/Registry/RegistryResource.swift
  3. Image Storage Layer – Persists OCI blobs and provides lazy access to configs and layers via Sources/ContainerResource/Image/ImageResource.swift
  4. Service Layer – Exposes CRUD APIs for images and containers in Sources/Services/ContainerImagesService/Server/ImagesService.swift
  5. CLI Commands Layer – Implements user-facing operations like ImagePull and ImagePush in Sources/ContainerCommands/Image/

Registry Communication Protocol

Reference Parsing and Validation

Registry interactions begin in Sources/ContainerResource/Registry/RegistryResource.swift. This file validates registry hostnames according to the OCI distribution spec and constructs ContainerizationOCI.Reference objects. The Reference.parse method converts user-supplied strings (e.g., ubuntu:22.04) into structured objects containing the registry host, repository path, and tag or digest.

The Pull Workflow

When executing ImagePull.swift, apple/container orchestrates a six-step OCI pull sequence:

  1. Reference parsing – The CLI invokes Reference.parse on the input string
  2. Registry lookupRegistryResource validates the hostname and builds the request URL (https://<registry>/v2/<name>/manifests/<reference>)
  3. Manifest retrieval – The service layer fetches the ContainerizationOCI.Manifest
  4. Platform selection – The code decodes ContainerizationOCI.Platform from the manifest to match the host architecture, falling back to the current platform if parsing fails via DefaultPlatform.swift
  5. Config and layer download – The system downloads ContainerizationOCI.ImageConfig and each layer blob, verifying digests and sizes
  6. Cache update – The ImageResource representing the pulled image is persisted to the system's EntityStore

The Push Workflow

The push implementation in Sources/ContainerCommands/Image/ImagePush.swift reverses the process:

  1. Reference creation – Builds a ContainerizationOCI.Reference from the target registry and tag
  2. Blob upload – Uploads each layer using the OCI blob upload endpoint (PUT /v2/<name>/blobs/uploads/<uuid>)
  3. Manifest upload – POSTs the completed manifest containing config digests, layer digests, and platform metadata
  4. Artifact linkingMachineBundle.swift can attach auxiliary OCI artifacts (such as SBOMs) via the OCI referrers API

Authentication Flow

Registry authentication is handled by Sources/ContainerCommands/Registry/RegistryLogin.swift and RegistryLogout.swift. These commands implement Docker-style token exchange against OCI registry authentication endpoints and store credentials securely in the local keychain. RegistryList.swift enumerates configured registries using the same validation logic found in RegistryResource.swift.

Platform-Aware Image Handling

Multi-platform image support relies on ContainerizationOCI.Platform.current, which reflects the host OS and architecture. When processing images with platform-specific variants, the code uses ContainerizationOCI.Platform(from:) to select the appropriate configuration. If the manifest specifies a different platform than the host, the system attempts to resolve it before falling back to the current platform configuration.

Practical Code Examples

Pull an Image

import ContainerizationOCI
import ContainerCommands

// Pull "ubuntu:22.04" from Docker Hub
let pull = ImagePull()
try await pull.run([
    "--repository", "docker.io/library/ubuntu",
    "--tag", "22.04"
])

Internally, ImagePull parses the reference, contacts the registry, downloads the manifest, config, and layers, and stores the result as an ImageResource.

Push a Local Image

import ContainerizationOCI
import ContainerCommands

let push = ImagePush()
try await push.run([
    "--repository", "myregistry.example.com/myimage",
    "--tag", "v1.0"
])

This command uploads each layer blob sequentially, then pushes the final manifest to the registry.

Authenticate to a Registry

import ContainerCommands

let login = RegistryLogin()
try await login.run([
    "--registry", "myregistry.example.com",
    "--username", "alice"
])

RegistryLogin performs the OCI token exchange and stores credentials for subsequent operations.

Summary

  • apple/container delegates OCI data modeling to the ContainerizationOCI package, which provides Swift-native types for Image, Manifest, Platform, and Reference
  • Registry interactions are centralized in Sources/ContainerResource/Registry/RegistryResource.swift, which validates hostnames and constructs OCI-compliant HTTP requests
  • Image pulls follow a six-phase workflow from reference parsing through EntityStore persistence, coordinated by ImagePull.swift and ImagesService.swift
  • Image pushes upload blobs via PUT /v2/<name>/blobs/uploads/<uuid> before POSTing the manifest, with support for OCI referrers in MachineBundle.swift
  • Authentication uses Docker-style token exchange implemented in RegistryLogin.swift and stores credentials in the system keychain

Frequently Asked Questions

What OCI specifications does apple/container implement?

apple/container implements the OCI Image Specification for manifests, configs, and layers, alongside the OCI Distribution Specification for registry communication. The ContainerizationOCI package provides the underlying data models that conform to these standards.

How does apple/container authenticate with private registries?

Authentication is handled by RegistryLogin.swift, which performs a Docker-style token exchange with the registry's authentication endpoint. Credentials are stored securely in the local system keychain and retrieved automatically during push and pull operations.

Can apple/container handle multi-platform OCI images?

Yes. The runtime uses ContainerizationOCI.Platform to parse platform descriptors from manifests and selects the appropriate image variant for the host architecture. If a specific platform is requested or the image requires emulation, the system resolves this via DefaultPlatform.swift before downloading layers.

Where does apple/container store OCI images locally?

Downloaded images are persisted as ImageResource objects managed by ImagesService.swift and stored in the system's EntityStore. Blobs are cached locally with verified digests, providing lazy access to image configurations and layers for container creation.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →