How Apple container Runs Linux Containers: Per-Container VM Architecture Explained
Problem
I had been using Docker Desktop on my Mac for years. It works, but I always wondered: how does it actually run Linux containers on macOS? The answer is a shared Linux VM. Every container runs inside that single VM, sharing one kernel.
This works, but it has a fundamental trade-off: isolation is at the namespace level, not the VM level. A container escape in one container could theoretically affect others in the same VM.
Apple container takes a different approach entirely.

The Architecture Overview
When I run container system start, here is what happens:
┌──────────────┐ ┌──────────────────────────────────────┐│ CLI/Client │────→│ container-apiserver ││ (container) │ │ (launchd-managed launch agent) │└──────────────┘ └───┬──────────┬────────────┬─────────┘ │ │ │ ▼ ▼ ▼ ┌────────────┐ ┌──────────┐ ┌────────────────┐ │core-images │ │network- │ │runtime-linux │ │(XPC helper)│ │vmnet │ │(XPC helper) │ │Image store │ │(vmnet │ │Per-container VM│ │management │ │framework)│ │lifecycle │ └────────────┘ └──────────┘ └────────────────┘- The CLI (
container) sends commands tocontainer-apiserver, a launch agent managed bylaunchd - The apiserver starts XPC helpers on boot:
container-core-images: manages the local OCI image storecontainer-network-vmnet: handles virtual networking via vmnet.framework
- Each
container runcreates a newcontainer-runtime-linuxXPC helper that manages a dedicated VM
Per-Container VM vs Shared VM
The fundamental difference:
| Aspect | Docker Desktop (Shared VM) | Apple container (Per-Container VM) |
|---|---|---|
| VMs running | 1 VM for all containers | 1 VM per container |
| Isolation | Namespace-level | VM-level (hardware backed) |
| Kernel sharing | All containers share one Linux kernel | Each container gets its own kernel |
| Container escape risk | One escape affects all containers | Escaped container is contained in its VM |
| Startup time | Fast (container just starts as process) | Comparable (optimized VM boot) |
| Resource overhead | One VM’s base overhead + containers | Per-VM overhead, but lightweight |
How the VM Boots So Fast
Each container runs a minimal Linux kernel with a small init system. The vminitd process handles early boot and then launches the OCI container’s process as PID 1.
The boot sequence for each container is:
1. container-apiserver receives container run request2. Spawns container-runtime-linux XPC helper3. Helper creates a VM via Virtualization.framework4. VM boots minimal Linux kernel (optimized config)5. vminitd starts as PID 16. vminitd launches the container's OCI entrypoint7. Container process is runningThis whole sequence completes in seconds, comparable to starting a container in a shared-VM setup.
macOS Framework Integration
Apple container is deeply integrated with native macOS frameworks:
- Virtualization.framework: creates and manages Linux VMs
- vmnet.framework: configures virtual network interfaces
- XPC: inter-process communication between the apiserver and its helpers
- launchd: manages the apiserver lifecycle (starts on demand, restarts on crash)
- Keychain: securely stores registry credentials
- Unified Logging: system-level logs for debugging
This native integration is a key advantage over cross-platform tools that run their own Linux VM with their own service management.
Why This Architecture Matters
The per-container VM design addresses real pain points:
- Security: A vulnerability in one container’s runtime cannot compromise another container. Each is isolated at the VM level.
- Privacy: When mounting data, only the target VM sees it. No need to mount everything into a shared VM.
- Performance: VMs are intentionally minimal — no unnecessary kernel modules, no extra services. Boot times stay fast.
- Resource control: Each VM manages its own CPU and memory allocation independently.
Summary
In this post, I explained how Apple container’s architecture differs from traditional shared-VM approaches. The key point is that by giving each container its own lightweight VM backed by macOS Virtualization.framework, Apple container provides VM-level isolation with container-level startup speed.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
- 👨💻 Apple container GitHub Repository
- 👨💻 Apple Virtualization.framework Documentation
- 👨💻 Apple Containerization Swift Package
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments