# How apple/container Achieves Per-Container VM Isolation

> Discover how apple/container employs per-container VM isolation using Apple Virtualization Framework for robust hardware-level sandboxing with dedicated kernels, filesystems, and networks.

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

---

**Apple's container project isolates each container by running it inside its own Apple Virtualization Framework virtual machine, providing complete hardware-level sandboxing through dedicated kernels, filesystems, and network interfaces.**

The apple/container repository implements a container runtime that achieves strong isolation by wrapping every container in a full virtual machine rather than relying on traditional Linux namespaces. This architecture leverages the Apple Virtualization Framework to create per-container VMs with independent kernels, root filesystems, and virtual network interfaces. By examining the source code in [`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift) and related components, we can trace exactly how the project transforms Docker-like container commands into isolated virtual machine instances.

## VM Lifecycle and Runtime Management

The isolation begins with the **RuntimeService** actor, defined in [`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift). This service acts as the orchestration layer that creates, boots, and tears down a `VZVirtualMachineManager` instance for every individual container.

When a container starts, the `bootstrap` method in [`Sources/Services/Runtime/RuntimeClient/RuntimeRoutes.swift`](https://github.com/apple/container/blob/main/Sources/Services/Runtime/RuntimeClient/RuntimeRoutes.swift) initiates the VM creation sequence. This method reads the container's `ContainerConfiguration`, assembles the kernel and initial filesystem, and hands these resources to the VM manager. Each container receives its own dedicated `VZVirtualMachineManager`, ensuring that processes inside one container cannot see or affect processes in another.

```swift
// RuntimeService boots the VM (simplified flow)
public func bootstrap(_ message: XPCMessage) async throws -> XPCMessage {
    // Load bundle → kernel + rootfs
    let bundle = ContainerResource.Bundle(path: self.root)
    var config = try bundle.configuration
    let kernel = try bundle.kernel

    // Build the VM manager
    let vmm = VZVirtualMachineManager(
        kernel: kernel,
        initialFilesystem: bundle.initialFilesystem.asMount,
        rosetta: config.rosetta,
        logger: self.log
    )
    
    // ... network attachment ...
    
    // Finally, start the VM
    try await vmm.start()
    return message.reply()
}

```

## Configuration and Resource Limits

Per-container resource constraints are enforced through the `ContainerConfiguration` struct defined in [`Sources/ContainerResource/Container/ContainerConfiguration.swift`](https://github.com/apple/container/blob/main/Sources/ContainerResource/Container/ContainerConfiguration.swift). This configuration stores limits for CPU cores, memory allocation, disk size, and nested virtualization capabilities.

The CLI command `container machine create` translates user-provided flags into this configuration via [`Sources/ContainerCommands/Machine/MachineCreate.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Machine/MachineCreate.swift). When the `VZVirtualMachineManager` instantiates the VM, it enforces these limits, guaranteeing that a runaway container cannot consume more host resources than allocated.

```swift
// Create a container "machine" (CLI command: container machine create)
let createCmd = MachineCreate()
try createCmd.run([
    "--name", "my-app",
    "--cpu", "2",
    "--memory", "4G",
    "--disk", "10G",
    "--nested-virt"   // enables nested virtualization on Apple Silicon M-series
])

```

## Kernel and Filesystem Isolation

Each container VM receives its own kernel image and root filesystem, completely isolated from the host's filesystem tree. The `ContainerResource.Bundle` class in [`Sources/ContainerResource/Bundle.swift`](https://github.com/apple/container/blob/main/Sources/ContainerResource/Bundle.swift) manages these resources, providing access to `bundle.kernel` and `bundle.initialFilesystem`.

These filesystem bundles are mounted read-only inside the VM, ensuring that the guest kernel operates within a confined environment. Because each VM boots its own Linux kernel (or other guest OS), containers achieve the same isolation guarantees as full virtual machines rather than shared-kernel containers.

## Network Isolation with vmnet

Network isolation is implemented through the **vmnet** virtual network framework. The `ReservedVmnetNetwork` class in [`Sources/Services/NetworkVmnet/Server/ReservedVmnetNetwork.swift`](https://github.com/apple/container/blob/main/Sources/Services/NetworkVmnet/Server/ReservedVmnetNetwork.swift) creates dedicated virtual network interfaces for each container VM.

Each VM receives its own MAC address and IP configuration that is invisible to other VMs. The `NonisolatedInterfaceStrategy` in [`Sources/Services/RuntimeLinux/Server/NonisolatedInterfaceStrategy.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/NonisolatedInterfaceStrategy.swift) (and related `InterfaceStrategy` types) determines whether a VM uses a dedicated vmnet interface or a shared host interface, allowing for flexible network topologies while maintaining isolation between containers.

During the bootstrap sequence, the runtime attaches these network interfaces to the VM before starting it:

```swift
// Attach network interfaces (via vmnet)
for (idx, netInfo) in try message.networkBootstrapInfos().enumerated() {
    let client = ContainerNetworkClient.NetworkClient(id: config.networks[idx].network,
                                                     plugin: netInfo.plugin)
    let session = client.connect()
    let (attachment, _) = try await client.allocate(hostname: …, on: session)
    vmm.attach(network: attachment)
}

```

## Guest-Agent Communication

After the VM boots, a lightweight **guest-agent** runs inside the VM to handle I/O forwarding, health reporting, and socket forwarding (such as SSH authentication sockets). This agent communicates with the host via XPC protocols defined in the `Sources/ContainerXPC` directory.

The XPC communication keeps the host-side implementation minimal and properly sandboxed. The guest-agent forwards sockets by listening on specific paths inside the VM:

```swift
// Guest-side agent (running inside the VM) forwards a socket
let socket = try Socket(path: RuntimeService.sshAuthSocketGuestPath)
try socket.listen()

```

This architecture ensures that container management operations occur through secure, inter-process communication rather than direct host access.

## Summary

- **Apple Virtualization Framework**: Each container runs inside its own `VZVirtualMachineManager` instance, providing hardware-level isolation.
- **Independent Resources**: Every VM receives dedicated CPU, memory, kernel images, and root filesystems managed through `ContainerConfiguration` and `ContainerResource.Bundle`.
- **Network Segmentation**: The `ReservedVmnetNetwork` implementation assigns unique MAC/IP addresses via vmnet, ensuring network traffic remains isolated between containers.
- **Secure Communication**: A guest-side agent communicates with the host via XPC protocols, enabling socket forwarding and health monitoring without compromising the isolation boundary.
- **Docker-like Interface**: Despite the VM architecture, the `container machine create` command provides a familiar CLI experience while generating full VM configurations.

## Frequently Asked Questions

### Does apple/container use Linux namespaces for isolation?

No. Unlike traditional container runtimes that rely on Linux namespaces and cgroups, apple/container achieves isolation by running each container inside a complete virtual machine using the Apple Virtualization Framework. This provides stronger security boundaries similar to full virtualization rather than process-level isolation.

### What virtualization framework does apple/container use?

The project uses Apple's native **Virtualization Framework** (`VZVirtualMachineManager`). This framework is specifically designed for Apple Silicon and Intel Macs, allowing the runtime to create lightweight VMs with near-native performance while maintaining strong isolation guarantees.

### How does networking isolation work in apple/container?

Each container VM connects to a dedicated **vmnet** virtual network created by `ReservedVmnetNetwork`. This assigns a unique MAC address and IP configuration to every container. The `InterfaceStrategy` determines whether the VM uses a host-only or shared network mode, but in all cases, the network interfaces remain isolated from other containers unless explicitly bridged.

### Can I run nested virtualization inside apple/container VMs?

Yes. The `ContainerConfiguration` supports nested virtualization flags that can be enabled via the `--nested-virt` option in the `container machine create` command. This allows running additional virtualization workloads (such as Docker-in-Docker or other hypervisors) inside the container VM on Apple Silicon M-series chips.