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 configurationContainerizationOCI.Manifest– Models the OCI manifest JSON structureContainerizationOCI.Platform– Encodes OS/architecture constraintsContainerizationOCI.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:
- OCI Model Layer – Defines index, config, manifest, and platform descriptors via the ContainerizationOCI package
- Registry Interaction Layer – Validates hostnames and constructs HTTP requests to OCI distribution endpoints (
/v2/…) inSources/ContainerResource/Registry/RegistryResource.swift - Image Storage Layer – Persists OCI blobs and provides lazy access to configs and layers via
Sources/ContainerResource/Image/ImageResource.swift - Service Layer – Exposes CRUD APIs for images and containers in
Sources/Services/ContainerImagesService/Server/ImagesService.swift - CLI Commands Layer – Implements user-facing operations like
ImagePullandImagePushinSources/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:
- Reference parsing – The CLI invokes
Reference.parseon the input string - Registry lookup –
RegistryResourcevalidates the hostname and builds the request URL (https://<registry>/v2/<name>/manifests/<reference>) - Manifest retrieval – The service layer fetches the
ContainerizationOCI.Manifest - Platform selection – The code decodes
ContainerizationOCI.Platformfrom the manifest to match the host architecture, falling back to the current platform if parsing fails viaDefaultPlatform.swift - Config and layer download – The system downloads
ContainerizationOCI.ImageConfigand each layer blob, verifying digests and sizes - Cache update – The
ImageResourcerepresenting the pulled image is persisted to the system'sEntityStore
The Push Workflow
The push implementation in Sources/ContainerCommands/Image/ImagePush.swift reverses the process:
- Reference creation – Builds a
ContainerizationOCI.Referencefrom the target registry and tag - Blob upload – Uploads each layer using the OCI blob upload endpoint (
PUT /v2/<name>/blobs/uploads/<uuid>) - Manifest upload – POSTs the completed manifest containing config digests, layer digests, and platform metadata
- Artifact linking –
MachineBundle.swiftcan 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, andReference - 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
EntityStorepersistence, coordinated byImagePull.swiftandImagesService.swift - Image pushes upload blobs via
PUT /v2/<name>/blobs/uploads/<uuid>before POSTing the manifest, with support for OCI referrers inMachineBundle.swift - Authentication uses Docker-style token exchange implemented in
RegistryLogin.swiftand 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →