# What Is Container Machine and How to Use It for Persistent Linux Environments

> Discover Container Machine, a powerful tool for creating persistent Linux VMs from OCI images. Experience full Linux environments with preserved state and macOS integration.

- Repository: [Apple/container](https://github.com/apple/container)
- Tags: how-to-guide
- Published: 2026-06-14

---

**Container machine is a sub-command of Apple's `container` tool that creates persistent Linux virtual machines from standard OCI images, enabling full Linux environments with init systems, preserved filesystem state, and seamless macOS home directory integration.**

Container machine is a sub-command of the Apple `container` tool that creates persistent Linux environments on macOS. Unlike traditional containers that run single processes, a container machine boots an entire Linux virtual machine from any OCI image containing `/sbin/init`, storing the root filesystem on disk for full state persistence between sessions.

## Architecture and Persistence Model

The `container machine` command leverages the macOS Virtualization Framework to provide lightweight VM performance while maintaining the flexibility of container workflows. According to the [technical overview](https://github.com/apple/container/blob/main/docs/technical-overview.md), this architecture bridges the gap between ephemeral containers and traditional virtual machines.

### OCI Image Format and Init System

Any OCI image containing `/sbin/init` can serve as a container machine base. The image is pulled, cached, and launched as a VM rather than a container process. As documented in [`docs/container-machine.md`](https://github.com/apple/container/blob/main/docs/container-machine.md), this requirement ensures the image includes a proper init system capable of managing services and user sessions.

### Host Integration and Filesystem Mounting

Container machines automatically integrate with the macOS host environment. The user's macOS username and `$HOME` directory are mounted inside the VM at `/home/<username>`, enabling seamless editing of source files on the Mac while building and running inside Linux. This mount behavior is configured through [`ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/ContainerSystemConfig.swift) and persists across machine restarts.

### Networking and DNS Resolution

Each container machine receives a dedicated virtual network interface managed by the host. Machines are reachable via locally scoped DNS names using the pattern `<name>.machine`, with the DNS zone managed by `container system dns`. This configuration is demonstrated in the VS Code integration example at [`examples/container-machine-vscode/README.md`](https://github.com/apple/container/blob/main/examples/container-machine-vscode/README.md).

## Creating and Managing Container Machines

The `container machine` CLI provides comprehensive lifecycle management for persistent Linux environments.

### Basic Creation and Startup

Create a new machine from any public or private OCI image:

```bash

# Create from Alpine image

container machine create alpine:latest --name dev

# Open interactive shell (automatically mounts $HOME)

container machine run -n dev

```

### Default Machine Configuration

Set a machine as the default to omit the `-n` flag in subsequent commands:

```bash
container machine set-default dev
container machine run

```

### Lifecycle Management

Manage running machines through standard lifecycle commands:

```bash

# List all machines

container machine ls

# Inspect machine configuration

container machine inspect dev

# Stop and preserve state

container machine stop dev

# Remove machine and persistent storage

container machine rm dev

```

## Custom Images and First-Boot Configuration

Container machines support custom images beyond standard distributions. Users can build specialized images (e.g., Ubuntu with systemd) and provide first-boot customization scripts.

### Bring Your Own Image

Build and use custom images through the standard container workflow:

```bash

# Build custom Ubuntu image

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

# Create machine from custom image

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

```

### First-Boot Customization

Add a [`/etc/machine/create-user.sh`](https://github.com/apple/container/blob/main//etc/machine/create-user.sh) script to your image for automatic user configuration on first boot. This script runs as root with the following environment variables available:

- `CONTAINER_USER`
- `CONTAINER_UID`
- `CONTAINER_GID`
- `CONTAINER_HOME`
- `CONTAINER_MACHINE_ID`

According to [`docs/container-machine.md`](https://github.com/apple/container/blob/main/docs/container-machine.md), this enables dynamic user creation and environment setup without manual intervention.

## Configuration and Resource Management

Machine-level defaults are stored in [`ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/ContainerSystemConfig.swift) and loaded from [`config.toml`](https://github.com/apple/container/blob/main/config.toml). These settings persist across system restarts and control resource allocation and mount behavior.

### Resource Allocation

Configure CPU count and memory size using the `set` subcommand. Changes take effect after the next stop and start cycle:

```bash

# Configure 4 CPUs and 8GB RAM

container machine set -n dev cpus=4 memory=8G

# Restart to apply changes

container machine stop dev
container machine run -n dev -- nproc  # Verifies 4 CPUs

```

### Configuration Persistence

The ` Sources/ContainerPersistence/ContainerSystemConfig.swift` file defines the on-disk configuration schema that drives persistence behavior. When you execute `container machine set`, the system updates the persisted JSON configuration stored alongside the machine's root filesystem.

## Summary

- **Container machine** creates persistent Linux VMs from OCI images using the macOS Virtualization Framework, as implemented in the `apple/container` repository.
- **State persistence** is achieved by storing the root filesystem on disk, preserving users, installed packages, and services between `stop` and `run` operations.
- **Host integration** automatically mounts macOS `$HOME` into the VM at `/home/<username>`, enabling seamless development workflows.
- **Custom images** support any OCI format with `/sbin/init`, including first-boot customization via [`/etc/machine/create-user.sh`](https://github.com/apple/container/blob/main//etc/machine/create-user.sh) with environment variables like `CONTAINER_USER` and `CONTAINER_HOME`.
- **Resource management** through `container machine set` updates [`ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/ContainerSystemConfig.swift) configurations, with changes effective after the next restart cycle.

## Frequently Asked Questions

### What is the difference between container machine and Docker?

Container machine boots a full Linux virtual machine with an init system from an OCI image, whereas Docker runs isolated processes without a persistent VM layer. In `apple/container`, the machine persists filesystem state across restarts, maintains running services, and provides DNS resolution via `<name>.machine`, offering a complete Linux environment rather than a single-process container.

### How does container machine persist data?

The VM's root filesystem is stored on disk according to the configuration in [`Sources/ContainerPersistence/ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/ContainerSystemConfig.swift). When you execute `container machine stop`, the entire state—including installed packages, user accounts, and running services—is preserved. Running `container machine run` restores the exact same filesystem, unlike ephemeral containers that reset on restart.

### Can I use custom Linux distributions?

Yes. Any OCI image containing `/sbin/init` can serve as a container machine base, as documented in [`docs/container-machine.md`](https://github.com/apple/container/blob/main/docs/container-machine.md). You can build custom images with specific init systems (such as systemd) and optionally include a [`/etc/machine/create-user.sh`](https://github.com/apple/container/blob/main//etc/machine/create-user.sh) script that runs once on first boot to customize the user account using environment variables like `CONTAINER_UID` and `CONTAINER_HOME`.

### How do I configure CPU and memory resources?

Use the `container machine set` command to adjust resources, which updates the persisted configuration loaded from [`config.toml`](https://github.com/apple/container/blob/main/config.toml) and defined in [`ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/ContainerSystemConfig.swift). For example, `container machine set -n dev cpus=4 memory=8G` configures the machine to use 4 CPU cores and 8GB of RAM, with changes taking effect after the next `container machine stop` and `container machine run` cycle.