# Architecture of the Containerization Swift Package Integration in apple/container

> Explore the layered architecture of Containerization Swift package integration in apple/container. Understand how Swift Package Manager separates modules like CLI, build engines, API services, and Linux runtime.

- Repository: [Apple/container](https://github.com/apple/container)
- Tags: architecture
- Published: 2026-06-22

---

**The apple/container toolkit implements a layered architecture that integrates the Containerization Swift package through Swift Package Manager, separating CLI interfaces, build engines, API services, and Linux runtime components into distinct modules that share common data models.**

The apple/container repository is a Swift-native container management system that treats the external Containerization package (hosted at https://github.com/apple/containerization) as its core dependency for OCI-compliant data structures and low-level APIs. This integration spans seven functional layers, from user-facing command-line tools to Linux-specific runtime implementations, ensuring consistent container models across all components.

## Architectural Layers of the Integration

The repository organizes Containerization package imports across seven distinct layers, each responsible for specific container management functions:

### CLI and Command Layer

The `container` binary and supporting command modules reside in `Sources/ContainerCommands/`. This layer imports `ContainerAPIClient`, `ContainerBuild`, `ContainerNetworkClient`, and `ContainerRuntimeClient` products to handle user input and delegate operations to backend services. For example, `SystemCommand` in [`Sources/ContainerCommands/System/SystemCommand.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/System/SystemCommand.swift) initializes the API client using Containerization-defined types to forward system-level requests.

### Build Engine

The `ContainerBuild` target depends on `Containerization`, `ContainerizationArchive`, `ContainerizationOCI`, and `ContainerizationExtras` to parse Dockerfiles, resolve image layers, and manage build caches. As declared in [`Package.swift`](https://github.com/apple/container/blob/main/Package.swift) (lines 28-38), these dependencies enable the build engine to generate OCI-compliant image specifications and communicate with builder servers using shared serialization formats.

### API Service and Client

Both the gRPC-based daemon (`container-apiserver`) and its client library rely on `Containerization`, `ContainerizationOS`, `ContainerizationExtras`, and `ContainerizationOCI` products (lines 34-36 of [`Package.swift`](https://github.com/apple/container/blob/main/Package.swift)). The `ContainerAPIService` and `ContainerAPIClient` targets use these imports to translate between Protocol Buffer messages and core container objects, ensuring that the API layer operates on canonical Containerization models defined in the external package.

### Linux Runtime

The `container-runtime-linux` executable and associated server code in [`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift) wrap Containerization runtime interfaces to launch containers. This layer imports `Containerization`, `ContainerizationExtras`, and `ContainerizationOS` to map high-level container specifications to Linux-specific constructs including namespaces, cgroups, and rootfs mounts.

### Network Management

Network configuration and plugin support utilize `ContainerizationExtras` for plugin handling and `ContainerizationOS` for network namespace manipulation. The `ContainerNetworkClient`, `ContainerNetworkServer`, and `ContainerNetworkVmnetServer` targets implement these capabilities, with commands like `NetworkCreate` in [`Sources/ContainerCommands/Network/NetworkCreate.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Network/NetworkCreate.swift) constructing `NetworkConfiguration` objects using Containerization types.

### Persistence and Configuration

State management for containers, images, and snapshots relies on `ContainerPersistence`, `ContainerVersion`, and `ContainerXPC` targets (lines 31-42 of [`Package.swift`](https://github.com/apple/container/blob/main/Package.swift)). These modules use `Containerization` for model definitions such as image descriptors and `ContainerizationExtras` for custom configuration parsing, storing data as JSON or TOML via [`ConfigurationLoader.swift`](https://github.com/apple/container/blob/main/ConfigurationLoader.swift).

### Utility Libraries

Supporting libraries including `TerminalProgress`, `ContainerLog`, and `SocketForwarder` provide progress rendering, logging, and socket forwarding capabilities. While these utilities do not directly import Containerization products, they support the higher-level services that depend on the package.

## Swift Package Manager Dependency Structure

The integration is defined in the root [`Package.swift`](https://github.com/apple/container/blob/main/Package.swift) file, which declares the Containerization dependency with exact version pinning to ensure API consistency across all targets.

```swift
.dependencies: [
    .package(url: "https://github.com/apple/containerization.git", exact: Version(stringLiteral: scVersion)),
],
.targets: [
    .executableTarget(name: "container", dependencies: ["ContainerAPIClient", "ContainerCommands"]),
    .target(name: "ContainerCommands", dependencies: [
        .product(name: "Containerization", package: "containerization"),
        .product(name: "ContainerizationOCI", package: "containerization"),
        .product(name: "ContainerizationOS", package: "containerization"),
        // Additional dependencies...
    ]),
]

```

The `exact` version constraint guarantees that every target consumes the same Containerization API surface. The `ContainerCommands` target explicitly imports `Containerization`, `ContainerizationOCI`, and `ContainerizationOS` to implement CLI operations, while service targets like `ContainerAPIService` and `ContainerRuntimeLinuxServer` declare similar product dependencies to maintain type consistency across the daemon, client, and plugin boundaries.

## Data Flow Across Architectural Layers

Containerization package types flow through the system in four distinct stages:

1. **CLI Parsing to API Client** – User commands such as `container image pull` instantiate Containerization-defined request objects in [`Sources/ContainerCommands/Image/ImagePull.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Image/ImagePull.swift), then forward them via `ContainerAPIClient`.

2. **API Client to gRPC Service** – The client communicates with `container-apiserver`, where `ContainerAPIService` translates Protocol Buffer messages into Containerization models like `ContainerizationOCI.Image` and `ContainerizationOS.ContainerConfig`.

3. **Service to Runtime Translation** – For container execution, `ContainerRuntimeClient` invokes `container-runtime-linux`, mapping high-level specs to Linux primitives using Containerization runtime interfaces in [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift).

4. **State Persistence** – All mutations persist through `ContainerPersistence`, which serializes Containerization model objects to disk in JSON or TOML format via [`ConfigurationLoader.swift`](https://github.com/apple/container/blob/main/ConfigurationLoader.swift).

## Practical Implementation Examples

The following patterns demonstrate typical Containerization API usage within the apple/container codebase:

### Creating Network Configurations

```swift
import ContainerAPIClient
import ContainerizationOCI
import ContainerizationExtras

// Create a network using Containerization models
let config = try NetworkConfiguration(
    name: "mynet",
    mode: .nat,
    ipv4Subnet: CIDRv4("10.0.0.0/24"),
    ipv6Subnet: nil,
    labels: ResourceLabels(),
    plugin: "container-network-vmnet",
    options: [:]
)
let client = NetworkClient()
let network = try await client.create(configuration: config)
print("Created network ID:", network.id)

```

This implementation in [`Sources/ContainerCommands/Network/NetworkCreate.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Network/NetworkCreate.swift) constructs a `NetworkConfiguration` struct from Containerization types before passing it to the client layer.

### Pulling Container Images

```swift
import ContainerAPIClient
import ContainerizationOCI

// Pull an image
let client = ImageClient()
let image = try await client.pull(named: "docker.io/library/alpine:latest")
print("Pulled image ID:", image.id)

```

The `ImagePull` command utilizes `ContainerAPIClient`, which internally references `ContainerizationOCI.Image` definitions to handle OCI-compliant image references.

## Summary

- The **apple/container** repository implements a seven-layer architecture that integrates the Containerization Swift package across CLI, build, API, runtime, network, persistence, and utility components.
- **Swift Package Manager** manages the dependency through an exact version pin (`scVersion`) declared in [`Package.swift`](https://github.com/apple/container/blob/main/Package.swift), ensuring consistent APIs across all targets.
- Key products imported include **`Containerization`**, **`ContainerizationOCI`**, **`ContainerizationOS`**, **`ContainerizationExtras`**, and **`ContainerizationArchive`**.
- The **gRPC-based API service** (`container-apiserver`) and **Linux runtime** (`container-runtime-linux`) both operate on Containerization-defined data models, translating between Protocol Buffer messages and Swift structs.
- State persistence relies on Containerization types stored via `ContainerPersistence`, maintaining consistency between runtime operations and disk storage.

## Frequently Asked Questions

### How is the Containerization package version controlled in apple/container?

The dependency uses an **exact version pin** specified by `scVersion` in [`Package.swift`](https://github.com/apple/container/blob/main/Package.swift). This constraint ensures that all targets compile against the same Containerization API surface, preventing version drift between the CLI, API service, and runtime components.

### What specific Containerization products does the build engine import?

The `ContainerBuild` target imports **`Containerization`**, **`ContainerizationArchive`**, **`ContainerizationOCI`**, and **`ContainerizationExtras`**. These products provide the necessary APIs for parsing image specifications, generating OCI-compliant layers, and communicating with builder servers.

### How does the CLI layer communicate with the Linux runtime?

The CLI forwards commands through **`ContainerAPIClient`**, which serializes requests using Containerization types and transmits them via gRPC to `container-apiserver`. The API service then delegates to **`ContainerRuntimeLinuxServer`**, which translates the high-level specifications into Linux namespace and cgroup operations using `ContainerizationOS` interfaces.

### Where are Containerization model objects persisted?

The **`ContainerPersistence`** target handles storage, using types defined in the Containerization package to serialize container state, image descriptors, and network configurations to disk. The implementation in [`Sources/ContainerPersistence/ConfigurationLoader.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/ConfigurationLoader.swift) supports both JSON and TOML formats for configuration files.