# How Apple Container Runtime Works on Apple Silicon: Architecture and Implementation

> Discover how Apple's container runtime on Apple Silicon leverages the Virtualization framework and RuntimeService actor for efficient, hardware-accelerated Linux container execution via XPC.

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

---

**Apple's container runtime executes Linux containers inside lightweight, hardware-accelerated virtual machines using the macOS Virtualization framework, orchestrated by the `RuntimeService` actor via secure XPC service calls.**

The `apple/container` repository provides Apple's open-source container runtime, which leverages Apple Silicon's hardware-assisted virtualization capabilities to run Linux workloads. Unlike traditional container engines that share the host kernel, this runtime boots a full Linux VM for each container, providing enhanced isolation while maintaining near-native performance through the Virtualization framework. The architecture centers on the `RuntimeService` actor, which manages the entire lifecycle from VM creation to process execution.

## Core Architecture

### Virtualization Framework Integration

At the foundation of the **Apple container runtime** is the `VZVirtualMachineManager` from the macOS Virtualization framework. According to the source code in [`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift), the runtime instantiates this manager to boot a Linux kernel and mount the container's root filesystem. This approach provides **hardware-accelerated virtualization** on Apple Silicon, utilizing the M-series CPU's virtualization extensions (KVM) to run the guest Linux environment.

### XPC Service Layer

The runtime operates as an XPC service named `container-runtime-linux`, launched by the `container-apiserver` launch agent. As implemented in [`Sources/Services/Runtime/RuntimeClient/RuntimeClient.swift`](https://github.com/apple/container/blob/main/Sources/Services/Runtime/RuntimeClient/RuntimeClient.swift), the service registers a Mach service (`com.apple.container.runtime.<runtime>.<id>`) to enable secure, sandboxed inter-process communication between the `container` CLI and the runtime backend. This design isolates the VM management logic from the user-facing CLI, improving security and stability.

### RuntimeService Actor

The **`RuntimeService`** actor serves as the heart of the runtime. Located in [`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift), this Swift actor handles critical XPC routes including `createEndpoint`, `start`, `stop`, `state`, and `statistics`. The `bootstrap` method (lines 31-53) performs the following sequence:

1. Verifies the bundle exists or creates it.
2. Reads the kernel and initial filesystem configuration.
3. Instantiates `VZVirtualMachineManager` with the specified resources.
4. Uses `lock.withLock` to enforce atomic state transitions from **created** to **booting**.
5. Allocates network attachments via `ContainerNetworkClient`.
6. Registers the XPC endpoint and starts the VM.

### Networking and Persistence

Network connectivity is established through the **`ContainerNetworkClient`**, which obtains a virtual network attachment from the `container-network-vmnet` helper and wires it to the host's `vmnet` framework. This creates a virtual NIC inside the guest VM.

Configuration persistence is handled by **`ContainerPersistence`** and defined in [`Sources/Services/Runtime/RuntimeClient/RuntimeConfiguration.swift`](https://github.com/apple/container/blob/main/Sources/Services/Runtime/RuntimeClient/RuntimeConfiguration.swift). The runtime stores VM settings—including kernel path, memory allocation, CPU count, and filesystem location—in a [`runtime-configuration.json`](https://github.com/apple/container/blob/main/runtime-configuration.json) file, enabling state recovery across service restarts.

## Apple Silicon Requirements

### Hardware Prerequisites

Running the **Apple container runtime** with full virtualization features requires **Apple Silicon M3 or later** with **macOS 15 or later**. According to [`docs/container-machine.md`](https://github.com/apple/container/blob/main/docs/container-machine.md) (line 79), these requirements are mandatory for nested virtualization support, which allows the guest Linux VM to run its own KVM workloads.

### Nested Virtualization Implementation

When the user specifies the `--virtualization` flag (documented in [`docs/command-reference.md`](https://github.com/apple/container/blob/main/docs/command-reference.md), lines 1087-1221), the runtime performs additional setup:

- Passes the **KVM device** (`/dev/kvm`) into the guest VM.
- Sets kernel command-line arguments to enable KVM (`"oops=panic"` and `"lsm=lockdown,capability,landlock,yama,apparmor"`).
- Verifies the host kernel supports KVM before exposing the device.

The guest kernel must be compiled with `CONFIG_KVM=y`. The default runtime kernel does not include this configuration, so users must supply a custom kernel path via the `--kernel` flag.

### Rosetta Configuration

On Apple Silicon, the runtime respects Rosetta settings for x86_64 binary translation. Users can disable Rosetta for builds by modifying `~/.config/container/config.toml`, as noted in [`docs/how-to.md`](https://github.com/apple/container/blob/main/docs/how-to.md) (line 676). This allows native ARM64 execution without translation overhead.

## Container Lifecycle Flow

### Bootstrap Sequence

The lifecycle begins when the user executes `container machine create` or similar commands:

1. **CLI → XPC**: The `container` CLI initializes a `RuntimeClient` and connects to the Mach service.
2. **Bundle Creation**: `RuntimeService.bootstrap` checks for the existence of the bundle at the configured path and creates it if necessary.
3. **VM Instantiation**: The service reads [`runtime-configuration.json`](https://github.com/apple/container/blob/main/runtime-configuration.json) and initializes `VZVirtualMachineManager` with the specified kernel and root filesystem.
4. **Network Setup**: `ContainerNetworkClient` acquires a network attachment from the vmnet helper.
5. **Initialization**: The VM boots, and the service registers the XPC endpoint for receiving further commands.

### Process Execution

To run a command inside the container, the CLI sends a `createProcess` XPC request. `RuntimeService` creates a `ProcessInfo` record, spawns the process inside the running VM, and returns a PID to the caller. This mechanism allows the host CLI to interact with processes running inside the isolated Linux environment.

### Shutdown

The `shutdown` method in `RuntimeService` handles teardown by stopping the VM, releasing network resources, and cleaning up temporary files. This ensures proper resource deallocation and prevents orphaned virtual machines.

## Code Examples

### Swift Client Implementation

The following Swift code demonstrates creating a `RuntimeClient` and establishing communication with the runtime service:

```swift
import ContainerXPC
import ContainerRuntimeClient

let client = try await RuntimeClient.create(
    id: "myContainer",           // Unique container ID
    runtime: "linux-sandboxd"   // Runtime name used in Mach service label
)

// Ask the runtime service to create an XPC endpoint
let endpointMessage = XPCMessage()
let reply = try await client.createEndpoint(endpointMessage)
let endpoint = reply.get(key: RuntimeKeys.runtimeServiceEndpoint.rawValue)

// Now you can send further commands (e.g., start a process) over this endpoint.

```

*This mirrors the logic in `RuntimeClient.create` and `RuntimeService.createEndpoint`.*

### CLI with Nested Virtualization

To create a container machine with KVM support on Apple Silicon M3 or later:

```bash

# Create a container machine with KVM support

container machine create \
    --virtualization \
    --kernel /path/to/vmlinux-kvm \
    --name kvm-dev \
    alpine:latest

# Verify that /dev/kvm is present inside the VM

container machine run -n kvm-dev -- ls -l /dev/kvm

```

*Documentation source:* [`docs/container-machine.md`](https://github.com/apple/container/blob/main/docs/container-machine.md).

### Runtime Configuration File

The runtime persists settings in [`runtime-configuration.json`](https://github.com/apple/container/blob/main/runtime-configuration.json):

```json
{
  "path": "/var/containers/myContainer",
  "initialFilesystem": "/var/containers/myContainer/rootfs",
  "kernel": "/path/to/vmlinux-kvm",
  "containerConfiguration": { "rosetta": false, "ssh": true },
  "runtimeData": null
}

```

This file is read by `RuntimeConfiguration.readRuntimeConfiguration` and written by `writeRuntimeConfiguration` in [`Sources/Services/Runtime/RuntimeClient/RuntimeConfiguration.swift`](https://github.com/apple/container/blob/main/Sources/Services/Runtime/RuntimeClient/RuntimeConfiguration.swift).

## Summary

- **Apple container runtime** runs each container inside a dedicated Linux VM using the macOS Virtualization framework and `VZVirtualMachineManager`.
- Communication occurs via the `container-runtime-linux` XPC service, with the `RuntimeService` actor managing VM lifecycle, networking, and process execution.
- Apple Silicon M3 or later with macOS 15+ is required for nested virtualization, which passes `/dev/kvm` into the guest when using the `--virtualization` flag.
- Configuration persists in [`runtime-configuration.json`](https://github.com/apple/container/blob/main/runtime-configuration.json), while network attachments are managed through `ContainerNetworkClient` and the `vmnet` framework.
- The `bootstrap` method in [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift) (lines 31-53) orchestrates VM creation, state transitions, and endpoint registration.

## Frequently Asked Questions

### What hardware is required to run Apple's container runtime with nested virtualization?

Nested virtualization requires **Apple Silicon M3 or later** running **macOS 15 or later**. These specifications ensure the host supports the Virtualization framework features necessary for passing the KVM device (`/dev/kvm`) into the guest VM. The guest kernel must also be compiled with `CONFIG_KVM=y`.

### How does the container CLI communicate with the runtime service?

The CLI communicates through **XPC (Inter-Process Communication)**. The `RuntimeClient` class in [`Sources/Services/Runtime/RuntimeClient/RuntimeClient.swift`](https://github.com/apple/container/blob/main/Sources/Services/Runtime/RuntimeClient/RuntimeClient.swift) constructs a Mach service label (`com.apple.container.runtime.<runtime>.<id>`) and sends messages to the `container-runtime-linux` XPC service. The `RuntimeService` actor receives these calls and manages the VM accordingly.

### Where does the runtime store VM configuration and state?

Configuration is stored in **[`runtime-configuration.json`](https://github.com/apple/container/blob/main/runtime-configuration.json)** within the container bundle. The `ContainerPersistence` class and `RuntimeConfiguration` struct in [`Sources/Services/Runtime/RuntimeClient/RuntimeConfiguration.swift`](https://github.com/apple/container/blob/main/Sources/Services/Runtime/RuntimeClient/RuntimeConfiguration.swift) handle reading and writing this file, preserving settings such as kernel path, memory limits, CPU count, and filesystem locations across restarts.

### Can I disable Rosetta translation for builds on Apple Silicon?

Yes. You can disable Rosetta translation by setting the appropriate option in **`~/.config/container/config.toml`**, as documented in [`docs/how-to.md`](https://github.com/apple/container/blob/main/docs/how-to.md) (line 676). This forces the runtime to use native ARM64 execution paths instead of x86_64 emulation, potentially improving build performance for native Apple Silicon workloads.