# How Apple's Container Runtime Works on Apple Silicon Macs: Linux VM Architecture Explained

> Discover how Apple's container runtime uses a Linux VM architecture on Apple Silicon Macs. Learn about its Virtualization framework and RuntimeService actor.

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

---

**Apple's container runtime leverages the macOS Virtualization framework to run each container inside a lightweight Linux virtual machine, orchestrated by the `RuntimeService` actor through a secure XPC service architecture.**

The `apple/container` repository provides a native container runtime for macOS that uses Apple Silicon hardware virtualization instead of traditional kernel namespaces. Each container operates within its own Linux VM created via the Virtualization framework, with the runtime exposed as the `container-runtime-linux` XPC service managed by the `container-apiserver` launch agent.

## Core Architecture Components

The runtime architecture consists of several Swift-based services that bridge the macOS Virtualization framework with container workflows.

### Virtualization Framework and VM Management

At the heart of the system lies the **Virtualization framework**, which creates a `VZVirtualMachineManager` instance to boot the Linux kernel and container root filesystem. This provides hardware-accelerated virtualization on Apple Silicon M-series CPUs using KVM-compatible virtualization extensions.

In [`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift), the `RuntimeService` actor instantiates the virtual machine manager and handles the complete lifecycle from bundle creation to shutdown. The service manages VM state transitions using `lock.withLock` to enforce valid transitions from `created` to `booting` and beyond.

### XPC Service Communication

The runtime exposes functionality through **XPC services** for secure inter-process communication. The `container-runtime-linux` service registers a Mach service using the label format `com.apple.container.runtime.<runtime>.<id>`, receiving RPCs from the `container` CLI via the `RuntimeClient` class.

The `RuntimeClient` implementation in [`Sources/Services/Runtime/RuntimeClient/RuntimeClient.swift`](https://github.com/apple/container/blob/main/Sources/Services/Runtime/RuntimeClient/RuntimeClient.swift) constructs the Mach service identifier and establishes the XPC connection to the runtime service.

### Networking and Persistence

The **ContainerNetworkClient** obtains network attachments from the `container-network-vmnet` helper and passes them to the VM, setting up a virtual NIC inside the guest that connects to the host's `vmnet` network. This logic appears in the `networkBootstrapInfos` loop within [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift).

Configuration persists through **ContainerPersistence**, which stores settings in [`runtime-configuration.json`](https://github.com/apple/container/blob/main/runtime-configuration.json). The `RuntimeConfiguration` struct in [`Sources/Services/Runtime/RuntimeClient/RuntimeConfiguration.swift`](https://github.com/apple/container/blob/main/Sources/Services/Runtime/RuntimeClient/RuntimeConfiguration.swift) handles reading and writing VM parameters including kernel path, memory allocation, and CPU count.

## Apple Silicon Requirements and Nested Virtualization

Running containers on Apple Silicon involves specific hardware requirements and optional nested virtualization support.

### Hardware Prerequisites

**Apple Silicon M3 or later** with **macOS 15 or later** is required for nested virtualization capabilities. The runtime checks for hardware-assisted virtualization support and requires the guest kernel to be built with `CONFIG_KVM=y` for nested VM functionality.

According to the documentation in [`docs/container-machine.md`](https://github.com/apple/container/blob/main/docs/container-machine.md) and [`docs/command-reference.md`](https://github.com/apple/container/blob/main/docs/command-reference.md), the `--virtualization` flag enables KVM device passthrough when the host supports it.

### KVM Device Passthrough

When users specify the `--virtualization` flag, the runtime passes the **KVM device** (`/dev/kvm`) into the guest VM. The `RuntimeService` verifies host kernel support before exposing the device, allowing the guest to run its own nested virtual machines.

The kernel command-line automatically includes security parameters `"oops=panic"` and `"lsm=lockdown,capability,landlock,yama,apparmor"` regardless of virtualization mode.

### Rosetta Configuration

On Apple Silicon systems, Rosetta translation can be disabled for builds via user configuration in `~/.config/container/config.toml`, as documented in [`docs/how-to.md`](https://github.com/apple/container/blob/main/docs/how-to.md).

## Container Lifecycle: From CLI to Running VM

The container lifecycle follows a structured bootstrap process managed by the `RuntimeService` actor.

### Bootstrap Sequence

1. **CLI Invocation**: The user runs `container machine create` with optional `--virtualization`. The CLI initializes a `RuntimeClient` and calls the `bootstrap` method.

2. **Bundle Preparation**: The `RuntimeService.bootstrap` method in [`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift) checks for bundle existence, creates it if missing, and reads the configuration from [`runtime-configuration.json`](https://github.com/apple/container/blob/main/runtime-configuration.json).

3. **VM Instantiation**: The service creates a `VZVirtualMachineManager` with the specified kernel and root filesystem, acquires the state lock, and allocates network attachments via `ContainerNetworkClient`.

4. **Endpoint Registration**: After starting the VM, the service registers an XPC endpoint via `createEndpoint` to accept further commands.

### Process Execution

Once booted, the CLI issues `container runtime start` or `container machine run`. The client sends an XPC `createProcess` request, and `RuntimeService` spawns a `ProcessInfo` inside the VM, returning a PID to the caller.

### Shutdown Procedures

The `RuntimeService.shutdown` method tears down the VM, cleans up networking resources, and removes temporary files, ensuring clean state transitions.

## Configuration and Code Examples

### Swift Client Implementation

Create a `RuntimeClient` and bootstrap the VM using the ContainerXPC framework:

```swift
import ContainerXPC
import ContainerRuntimeClient

let client = try await RuntimeClient.create(
    id: "myContainer",
    runtime: "linux-sandboxd"
)

let endpointMessage = XPCMessage()
let reply = try await client.createEndpoint(endpointMessage)
let endpoint = reply.get(key: RuntimeKeys.runtimeServiceEndpoint.rawValue)

```

This mirrors the implementation in [`RuntimeClient.swift`](https://github.com/apple/container/blob/main/RuntimeClient.swift) and [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift), establishing the Mach service connection and creating the XPC endpoint for subsequent operations.

### CLI Commands for Nested Virtualization

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

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

```

Verify KVM device availability inside the container:

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

```

These examples reference the documentation in [`docs/container-machine.md`](https://github.com/apple/container/blob/main/docs/container-machine.md).

### Runtime Configuration File

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

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

```

The `RuntimeConfiguration.readRuntimeConfiguration` and `writeRuntimeConfiguration` methods in [`RuntimeConfiguration.swift`](https://github.com/apple/container/blob/main/RuntimeConfiguration.swift) manage this persistence layer.

## Summary

- Apple's container runtime uses the **macOS Virtualization framework** to run containers inside lightweight Linux VMs on Apple Silicon, rather than using kernel namespaces.
- The **`RuntimeService`** actor in [`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift) manages the complete VM lifecycle, networking via `ContainerNetworkClient`, and XPC communication.
- **Apple Silicon M3 or later** with macOS 15 or later is required for nested virtualization with KVM device passthrough.
- The runtime communicates via **XPC services** using Mach service labels formatted as `com.apple.container.runtime.<runtime>.<id>`.
- Configuration persists in **[`runtime-configuration.json`](https://github.com/apple/container/blob/main/runtime-configuration.json)**, managed by the `RuntimeConfiguration` struct.

## Frequently Asked Questions

### What virtualization technology does Apple's container runtime use on Apple Silicon?

The runtime uses the **macOS Virtualization framework** (`VZVirtualMachineManager`) to create hardware-accelerated Linux VMs. It leverages the Apple Silicon M-series CPU's virtualization extensions to provide KVM-compatible nested virtualization when running on M3 or later with macOS 15.

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

The `container` CLI creates a **`RuntimeClient`** that connects to the `container-runtime-linux` XPC service. This service registers a Mach service with the label `com.apple.container.runtime.<runtime>.<id>` and exposes methods like `bootstrap`, `createEndpoint`, and `createProcess` for VM lifecycle management.

### What are the requirements for running nested virtualization in Apple container machines?

Nested virtualization requires **Apple Silicon M3 or later** and **macOS 15 or later**. You must supply a custom kernel built with `CONFIG_KVM=y` and use the `--virtualization` flag when creating the machine. The runtime then passes `/dev/kvm` into the guest VM.

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

The runtime persists configuration in **[`runtime-configuration.json`](https://github.com/apple/container/blob/main/runtime-configuration.json)** using the `ContainerPersistence` layer. The `RuntimeConfiguration` struct in [`Sources/Services/Runtime/RuntimeClient/RuntimeConfiguration.swift`](https://github.com/apple/container/blob/main/Sources/Services/Runtime/RuntimeClient/RuntimeConfiguration.swift) handles serialization of kernel paths, memory settings, CPU count, and Rosetta configuration options.