# How apple/container Interacts with the Underlying Operating System

> Discover how apple/container interacts with macOS using Virtualization vmnet XPC and launchd to run Linux VMs. Orchestrate the entire stack in Swift without external binaries.

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

---

**The `apple/container` repository leverages macOS system frameworks including Virtualization, vmnet, XPC, and launchd to run Linux containers inside lightweight VMs, orchestrating the entire stack through pure Swift without invoking external binaries.**

The `apple/container` project is a Swift-based container runtime that enables Linux containers to run natively on macOS. Understanding how this tool interacts with the underlying operating system reveals a sophisticated architecture that bridges macOS system services with Linux virtualization. This analysis examines the specific mechanisms, frameworks, and source code implementations that enable containerized workloads on macOS.

## Three-Layer Architecture

The interaction between `apple/container` and macOS operates through three distinct layers, each utilizing specific native frameworks to maintain security and performance.

### CLI to Daemon Communication via XPC

When users execute commands like `container system start` or `container run`, the CLI communicates with the `container-apiserver` daemon through Apple's **XPC** (inter-process communication) mechanism. According to [`docs/technical-overview.md`](https://github.com/apple/container/blob/main/docs/technical-overview.md), this design leverages `launchd` for service management, ensuring the daemon starts on demand and runs with appropriate privileges. The CLI establishes an anonymous XPC connection, sends a `createEndpoint` request, and receives an endpoint that facilitates subsequent daemon interactions.

### Daemon to Virtual Machine Management

The `container-apiserver` spawns a per-container helper called `container-runtime-linux`, which creates and manages lightweight Linux virtual machines. In [`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift), the `bootstrap` method initializes a `VZVirtualMachineManager` with a custom Linux kernel, root filesystem, and optional Rosetta support for x86_64 emulation. This layer utilizes the **Virtualization framework** for VM management and the **vmnet framework** for virtual networking, creating isolated network interfaces for each container through `ContainerNetworkClient`.

### VM to Linux Userspace Bridge

Inside the VM, the runtime translates OCI (Open Container Initiative) specifications into Linux process configurations. The `configureProcessConfig` and `addNewProcess` methods in [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift) handle process creation, while `ContainerizationOS/ContainerizationExtras` provides Swift wrappers for OCI compliance. The `SocketForwarder` components (found in `Sources/SocketForwarder/`) manage TCP and UDP port forwarding between the host macOS system and the container VM.

## Step-by-Step OS Interaction Flow

The complete lifecycle of container execution follows this precise sequence:

1. **Launchd initiates the daemon** – When the user runs `container system start`, launchd loads the `container-apiserver` launch agent as documented in [`docs/technical-overview.md`](https://github.com/apple/container/blob/main/docs/technical-overview.md).

2. **XPC handshake establishment** – The CLI opens an anonymous XPC connection, sends a `createEndpoint` request, and receives an XPC endpoint pointing to the daemon, implemented in `RuntimeService.createEndpoint`.

3. **VM bootstrapping** – On the first `container run` invocation, the daemon calls `RuntimeService.bootstrap`, which configures the `VZVirtualMachineManager` with kernel and filesystem parameters (lines 65-68 in [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift)).

4. **Network virtualization** – The daemon uses the vmnet framework to create virtual network devices, assigning each container its own network attachment via `ContainerNetworkClient`.

5. **Process creation** – The container runtime receives a `createProcess` XPC call through `ContainersService`, translating OCI `ProcessConfiguration` into `LinuxProcessConfiguration`, registering the process with an `ExitMonitor`, and spawning the Linux process inside the VM.

6. **I/O forwarding** – `SocketForwarder` components (including [`TCPForwarder.swift`](https://github.com/apple/container/blob/main/TCPForwarder.swift) and [`UDPForwarder.swift`](https://github.com/apple/container/blob/main/UDPForwarder.swift)) forward stdin/stdout/stderr and port-forwarding requests between the host and VM.

7. **Lifecycle monitoring** – The daemon watches for process exits via `ExitMonitor` and reports status back to the CLI through XPC.

## Key macOS Frameworks Utilized

- **Virtualization Framework** – Provides the `VZVirtualMachineManager` API for creating and managing Linux VMs with hardware virtualization support.

- **vmnet Framework** – Enables virtual network interface creation, allowing containers to have isolated network stacks while communicating with the host.

- **XPC Services** – Facilitates secure, efficient inter-process communication between the CLI client and the persistent daemon.

- **launchd** – Manages the daemon lifecycle, ensuring `container-apiserver` starts on demand and integrates with macOS service management.

- **SystemPackage** – Provides low-level system call wrappers used by the runtime for process management within the VM.

## Source Code Implementation Details

The interaction patterns are implemented across several critical files:

- **[`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift)** – Core VM management showing Virtualization framework usage, XPC endpoint creation, and process bookkeeping via `ExitMonitor`.

- **[`Sources/Services/ContainerAPIService/Server/Containers/ContainersService.swift`](https://github.com/apple/container/blob/main/Sources/Services/ContainerAPIService/Server/Containers/ContainersService.swift)** – Implements XPC-based container API including `createProcess` and `startProcess` methods.

- **`Sources/SocketForwarder/`** – Contains [`TCPForwarder.swift`](https://github.com/apple/container/blob/main/TCPForwarder.swift) and [`UDPForwarder.swift`](https://github.com/apple/container/blob/main/UDPForwarder.swift) for network bridging between host and container.

- **[`Package.swift`](https://github.com/apple/container/blob/main/Package.swift)** – Declares dependencies on `Virtualization`, `vmnet`, and other Apple frameworks required for OS integration.

- **[`scripts/update-container.sh`](https://github.com/apple/container/blob/main/scripts/update-container.sh)** – Handles installation and launchd registration for the container service.

## Practical Usage Examples

Start the container system and daemon:

```bash
container system start

```

Run an interactive container:

```bash
container run --rm -it docker.io/library/alpine:latest /bin/sh

```

Programmatically create a process using the Swift XPC client:

```swift
import ContainerXPC
import ContainerizationOCI

let client = RuntimeClient(xpcEndpoint: endpoint)
let procConfig = ProcessConfiguration(
    args: ["/usr/bin/ls", "-la"],
    env: ["PATH": "/usr/bin"]
)
let stdio: [FileHandle?] = [
    FileHandle.standardInput,
    FileHandle.standardOutput,
    FileHandle.standardError
]

let createMsg = XPCMessage(route: RuntimeRoutes.createProcess.rawValue)
let reply = try await client.send(
    createMsg,
    payload: ProcessCreateRequest(
        id: "myproc",
        config: procConfig,
        stdio: stdio
    )
)

try await client.startProcess(id: "myproc")

```

## Summary

- `apple/container` operates entirely within macOS user space using Swift, with no external binary dependencies.
- The architecture relies on XPC for CLI-to-daemon communication, the Virtualization framework for Linux VMs, and vmnet for networking.
- Process lifecycle management occurs through [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift) and [`ContainersService.swift`](https://github.com/apple/container/blob/main/ContainersService.swift), utilizing `ExitMonitor` for tracking container processes.
- All host OS interactions are mediated through Apple's public frameworks, ensuring security and system integration.

## Frequently Asked Questions

### How does apple/container communicate between the CLI and daemon?

The CLI communicates with the `container-apiserver` daemon through **XPC** (inter-process communication), a macOS technology that provides secure, efficient message passing between processes. When you run commands like `container run`, the CLI establishes an anonymous XPC connection and sends structured requests to the daemon, which are handled by methods such as `RuntimeService.createEndpoint` in [`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift).

### What macOS frameworks enable the Linux virtual machine functionality?

The implementation relies on the **Virtualization framework** (`VZVirtualMachineManager`) for creating and managing Linux VMs, the **vmnet framework** for virtual network interface creation, and **XPC** for inter-process communication. These frameworks are declared as dependencies in [`Package.swift`](https://github.com/apple/container/blob/main/Package.swift) and are utilized throughout [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift) to bootstrap VMs and manage container networking.

### How are processes created and monitored inside the container VM?

Process creation follows an OCI-to-Linux translation pattern. The daemon receives `createProcess` XPC calls through [`ContainersService.swift`](https://github.com/apple/container/blob/main/ContainersService.swift), translates the OCI `ProcessConfiguration` into `LinuxProcessConfiguration`, and spawns the process inside the VM using methods like `addNewProcess`. The `ExitMonitor` class tracks process lifecycle, while `SocketForwarder` components handle I/O forwarding between the host and container.

### Does apple/container require external binaries or Docker Desktop?

No, `apple/container` is implemented entirely in Swift and interacts with the operating system purely through Apple's public frameworks. As documented in the source code, no external binaries are invoked; the tool uses `launchd` for service management, the Virtualization framework for VMs, and direct system calls via SystemPackage for process management.