How to Use OCI Images with Container: Pull, Run, and Manage OCI-Compliant Images
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 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. 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. 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 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. 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:
container image pull docker://alpine:latest
List locally cached OCI images:
container image list
Run a container from a pulled image:
container run \
--image docker://alpine:latest \
--cmd /bin/sh
Save an OCI image as a tar archive:
container image save \
--image docker://alpine:latest \
--output alpine.tar
Push a locally built image to a private registry:
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.
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
ContainerizationOCISwift package. - Reference normalization occurs via
ClientImage.normalizeReferenceinSources/ContainerCommands/Image/ImagePull.swift, validating and canonicalizing image strings. - Platform resolution uses
DefaultPlatform.resolveto handle multi-architecture images via--os,--arch, and--platformflags. - Image fetching streams manifests and layers through
ClientImage.pull, while unpacking is handled byImage.unpackbefore runtime execution. - CLI commands like
image pull,image list,run,save, andpushprovide 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.
How does container handle multi-platform OCI images?
Multi-platform support is resolved through DefaultPlatform.resolve in 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), which maintains the OCI config, size, and digests for local caching and runtime usage.
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 →