# Internal Architecture of Apple's Container Tool: A Deep Dive into the Swift-Based OCI Runtime

> Explore Apple's Swift-based container tool architecture. Learn about its CLI frontend, XPC daemon, and Virtualization framework helpers for running Linux on macOS.

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

---

**Apple’s container tool implements a three-tier Swift architecture consisting of a CLI frontend, an XPC-based daemon (container-apiserver), and per-container helpers that leverage the Virtualization framework to run Linux workloads on macOS.**

The `apple/container` repository provides a complete OCI-compatible container runtime specifically designed for macOS 26 and Apple silicon. Understanding the internal architecture of Apple's container tool reveals how it bridges native macOS frameworks like Virtualization, vmnet, and XPC with Linux container standards to deliver native container performance without traditional virtualization overhead.

## Overview of the Three-Layer Architecture

The codebase organizes functionality into three distinct logical layers, each implemented in Swift and communicating via XPC (Inter-Process Communication).

**Layer 1: CLI & User-Facing Commands**
The command-line interface parses user input and forwards operations to the daemon via XPC. It handles image-related operations by communicating with the OCI-compatible content store.

**Layer 2: Daemon (`container-apiserver`)**
Running as a Launch Daemon, this component owns the XPC server that services CLI requests. It manages route tables mapping command strings to async handlers and launches per-container helpers as needed.

**Layer 3: Helpers & Runtime**
Specialized binaries handle specific concerns:
- `container-runtime-linux` – Runs inside a lightweight Linux VM per container
- `container-core-images` – Handles image pull/push operations and local storage
- `container-network-vmnet` – Manages virtual networking using macOS's vmnet framework

## CLI to Daemon Communication via XPC

When you execute `container run`, the CLI constructs an `XPCMessage` defined in [`Sources/ContainerXPC/XPCMessage.swift`](https://github.com/apple/container/blob/main/Sources/ContainerXPC/XPCMessage.swift). This struct encodes a route key (e.g., `com.apple.container.xpc.route`) along with payload data, then transmits it over an XPC connection to the daemon.

The daemon's [`XPCServer.swift`](https://github.com/apple/container/blob/main/XPCServer.swift) maintains a route table mapping strings to handler closures:

```swift
let routes: [String: XPCServer.RouteHandler] = [
    "container.create": XPCServer.route { message in
        // decode request, spin up a VM, return container ID
    },
    "image.pull": XPCServer.route { message in
        // handle image download
    }
]

```

The server validates the client's EUID, extracts the route, invokes the corresponding async handler, and replies with either success data or a `ContainerizationError` encoded via `ContainerXPCError`.

## Per-Container Runtime and Virtualization

For each container, the daemon spawns `container-runtime-linux`, a helper binary executing inside its own lightweight VM created through the **Containerization** Swift package. This package wraps Apple's `Virtualization` framework to instantiate minimal Linux VMs without the overhead of traditional hypervisors.

The VM runs a minimal Linux kernel with a userspace init that forwards container-specific syscalls to the host. Network bridging occurs through the **SocketForwarder** module ([`Sources/SocketForwarder/TCPForwarder.swift`](https://github.com/apple/container/blob/main/Sources/SocketForwarder/TCPForwarder.swift)), which proxies TCP and UDP traffic between host and container:

```swift
import SocketForwarder

let forwarder = TCPForwarder(
    listenPort: 8080,
    destinationHost: "127.0.0.1",
    destinationPort: 80
)
try forwarder.start()

```

## Image Management and OCI Compatibility

Image operations flow through the `container-core-images` helper, which implements the OCI distribution specification. Stored in `~/.container`, the local content cache maintains OCI-compliant image layers.

The helper authenticates to remote registries using credentials stored securely in the macOS **Keychain**. The flow follows this pattern:

1. CLI sends XPC request to `container-core-images` (route: `image.pull`)
2. Helper queries Keychain for registry credentials
3. Downloads manifest and layers to the local OCI store
4. Returns an OCI-compatible image reference to the daemon for runtime mounting

## Virtual Networking with vmnet

Network isolation leverages the `vmnet` framework available on macOS. The `container-network-vmnet` helper owns virtual network interfaces and assigns IP addresses to container VMs dynamically.

On macOS 26, the tool supports multiple isolated networks simultaneously. On macOS 15, only a single default network is available, as documented in the technical overview.

## Configuration and Persistence

System-wide configuration resides in `~/.container/config.toml`, parsed into Swift structs defined in [`Sources/ContainerPersistence/ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/ContainerSystemConfig.swift). The configuration hierarchy includes:

- `BuildConfig` – Builder image specifications and resource limits
- `ContainerConfig` – Default CPU and memory allocations
- `NetworkConfig` – Subnet overrides and DNS settings
- `KernelConfig` – Path to the Linux kernel binary
- `VminitConfig` – Initialization helper image settings

Each field provides sensible defaults, enabling immediate usability without manual configuration:

```swift
import ContainerPersistence

let configURL = URL(fileURLWithPath: "\(NSHomeDirectory())/.container/config.toml")
let loader = ConfigurationLoader()
let systemConfig = try loader.load(from: configURL)
print("Default container memory: \(systemConfig.container.memory)")

```

## Summary

- **Three-tier architecture**: CLI frontend, XPC daemon (container-apiserver), and specialized runtime helpers
- **XPC communication**: All components communicate via `XPCMessage` and `XPCServer` with route-based dispatch
- **Virtualization**: Uses Apple's `Virtualization` framework via the Containerization package for lightweight per-container VMs
- **Image management**: OCI-compatible storage in `~/.container` with Keychain-backed registry authentication
- **Networking**: vmnet-based virtual interfaces managed by `container-network-vmnet`
- **Configuration**: TOML-based system config parsed into Swift structs via [`ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/ContainerSystemConfig.swift)

## Frequently Asked Questions

### How does the CLI communicate with the container daemon?

The CLI sends XPC messages to the daemon using the `XPCMessage` struct defined in [`Sources/ContainerXPC/XPCMessage.swift`](https://github.com/apple/container/blob/main/Sources/ContainerXPC/XPCMessage.swift). Each message includes a route key (like `"container.create"`) that the daemon's [`XPCServer.swift`](https://github.com/apple/container/blob/main/XPCServer.swift) maps to specific handler closures, enabling type-safe async communication between processes.

### What framework enables Linux containers to run on macOS?

The tool uses Apple's native `Virtualization` framework wrapped by the Containerization Swift package. This framework creates lightweight VMs for each container without traditional hypervisor overhead, running a minimal Linux kernel inside `container-runtime-linux`.

### Where does the tool store container images locally?

Images are stored in an OCI-compliant content store located at `~/.container`. The `container-core-images` helper manages this directory, handling layer deduplication and manifest storage according to the OCI distribution specification.

### How is networking implemented between the host and containers?

Networking utilizes macOS's `vmnet` framework through the `container-network-vmnet` helper. This creates virtual network interfaces that bridge traffic between the host and container VMs, with traffic forwarding handled by `SocketForwarder` modules for TCP and UDP protocols.