# What Are Container Machines in Apple's Container Runtime?

> Discover container machines in Apple's container runtime. Learn how this persistent Linux environment integrates with macOS, behaving like a lightweight VM.

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

---

**A container machine is a persistent Linux environment built from OCI images that runs an init system like systemd, shares your macOS home directory, and behaves like a lightweight VM integrated with Apple's container runtime.**

Container machines in the `apple/container` repository represent a specialized abstraction that bridges ephemeral application containers and full virtual machines. Unlike standard containers designed for single-process isolation, these machines provide a complete, bootable Linux userspace with persistent storage and tight macOS integration. They enable developers to run long-running services, test process supervisors, and maintain a true Linux filesystem hierarchy while retaining native macOS file access.

## Understanding Container Machine Architecture

### OCI-Based Images with Init System Support

Container machines are constructed from standard OCI images that contain `/sbin/init`, allowing them to function as lightweight Linux distributions rather than isolated application bundles. According to [`docs/container-machine.md`](https://github.com/apple/container/blob/main/docs/container-machine.md), the image must provide an init system because the container machine boots a full Linux environment capable of running persistent daemons and services.

### Persistent Filesystem and Configuration

The filesystem created for a container machine survives restarts and is stored on disk, providing a "persistent VM" feel. Configuration parameters including CPU count, memory allocation, and home-mount settings are serialized to a JSON `MachineConfig` file. As implemented in [`Sources/ContainerPersistence/MachineConfig.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/MachineConfig.swift), the `MachineConfig` struct encodes these settings and validates kernel paths through the `validateKernelPath` method when nested virtualization is enabled.

## macOS Integration and User Space Sharing

### Automatic Home Directory Mapping

When you create a container machine, the host username and `$HOME` directory are automatically mapped into the Linux environment. This creates a bidirectional share between `/Users/<username>` on macOS and `/home/<user>` in the container, making dotfiles, SSH keys, and repositories immediately available without file copying or manual volume mounting.

### Resource Management via MachineConfig

Dynamic resource adjustments are handled through the `MachineConfig` structure persisted via [`Sources/ContainerPersistence/ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/ContainerSystemConfig.swift). Changes to CPU, memory, or mount options are written to disk and applied on the next boot cycle, allowing you to resize machines without recreation.

## CLI Lifecycle Management

### Creating and Booting Machines

The `container machine` subcommand (aliased as `m`) drives the complete lifecycle. The implementation in [`Sources/ContainerCommands/Machine/MachineCreate.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Machine/MachineCreate.swift) handles image resolution, kernel validation for virtualization support, and initial boot sequencing.

```bash
container machine create alpine:latest --name dev

```

### Running Commands and Interactive Shells

The [`MachineRun.swift`](https://github.com/apple/container/blob/main/MachineRun.swift) source file implements the `container machine run` command, which can execute single commands or spawn interactive login shells matching your macOS username. If the machine is stopped, the run command automatically boots it first.

```bash

# Run a single command

container machine run -n dev uname -a

# Open an interactive login shell

container machine run -n dev

```

You can also set a default machine to avoid specifying the `-n` flag repeatedly:

```bash
container machine set-default dev
container machine run            # operates on the default machine

```

## Advanced Capabilities

### Nested Virtualization Support

On Apple Silicon M3+ systems running macOS 15+, container machines can expose `/dev/kvm` to run nested VMs. The kernel path is validated by `MachineConfig.validateKernelPath` in [`MachineConfig.swift`](https://github.com/apple/container/blob/main/MachineConfig.swift) before boot.

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

```

### Custom Image Requirements

Any Linux image containing `/sbin/init` can serve as a container machine base. Custom images typically install systemd, essential tools, and a [`create-user.sh`](https://github.com/apple/container/blob/main/create-user.sh) script that executes on first boot to establish the user environment.

```bash

# Build custom image with systemd and init support

container build -t local/ubuntu-machine:latest .

# Create machine from custom image

container machine create local/ubuntu-machine:latest --name ubuntu

```

Resource adjustments can be applied dynamically using the `set` subcommand documented in [`docs/command-reference.md`](https://github.com/apple/container/blob/main/docs/command-reference.md):

```bash
container machine set -n dev cpus=4 memory=8G home-mount=ro
container machine stop dev
container machine run -n dev nproc   # shows the new CPU count

```

## Summary

- Container machines provide persistent Linux environments with init systems, bridging the gap between containers and VMs in Apple's container runtime.
- Configuration is managed through the `MachineConfig` struct and stored in JSON files by [`ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/ContainerSystemConfig.swift) for persistence across reboots.
- Automatic user and home directory mapping creates seamless macOS integration without manual volume configuration.
- The CLI supports full lifecycle management through `container machine` subcommands including create, run, set, and inspect.
- Advanced features include nested virtualization support on M3+ hardware via `validateKernelPath` and compatibility with custom OCI images containing `/sbin/init`.

## Frequently Asked Questions

### What is the difference between a container machine and a regular container?

A regular container typically runs a single application process in an isolated environment, while a container machine boots a full Linux system with an init process like systemd. Container machines persist their filesystem across restarts and share your macOS home directory, functioning more like lightweight VMs than ephemeral application containers.

### How does container machine persistence work?

The filesystem is stored on disk and survives reboots, while configuration changes are written to a `MachineConfig` JSON file as implemented in [`Sources/ContainerPersistence/MachineConfig.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/MachineConfig.swift). Resources and settings are applied on the next boot, allowing you to modify CPU, memory, and mount options without recreating the machine.

### Can I run Docker inside a container machine?

Yes, when running on Apple Silicon M3+ with macOS 15+, you can enable nested virtualization by providing a KVM-capable kernel via the `--kernel` flag. This exposes `/dev/kvm` inside the container machine, allowing you to run nested VMs or container runtimes that require hardware virtualization.

### Where is the container machine configuration stored?

Configuration is persisted in a JSON `MachineConfig` file managed by [`Sources/ContainerPersistence/ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/ContainerSystemConfig.swift). This file stores CPU counts, memory limits, home-mount settings, and kernel paths, encoding the `MachineConfig` struct defined in [`Sources/ContainerPersistence/MachineConfig.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/MachineConfig.swift).