# Container Machine vs Regular Container Instance: Key Differences in Apple Container

> Understand the key differences between Apple Container Machine and regular container instances. Learn how persistent VMs differ from ephemeral single application processes.

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

---

**A container machine is a persistent Linux VM modeled after an entire environment with an init system and user home mapping, while a regular container instance is an ephemeral, single-application process that exits when the command completes.**

The `apple/container` repository provides a lightweight container runtime for macOS that supports two distinct execution models. While both leverage the same underlying virtualization technology, they differ fundamentally in architecture, lifecycle management, and intended use cases. Understanding these distinctions helps developers choose the right abstraction for development workflows versus production workloads.

## Architectural Model: Environment vs Application

The primary distinction lies in what each abstraction models.

**Container machines** are modeled after an entire Linux **environment**—essentially a full virtual machine with an init system. According to the project documentation in [`docs/container-machine.md`](https://github.com/apple/container/blob/main/docs/container-machine.md), "Containers are typically modeled after an application. A container machine is modeled after a Linux environment." This means the machine boots like a traditional Linux system, runs `/sbin/init`, and maintains persistent state across sessions.

**Regular container instances** are modeled after a single **application**. The container runs exactly one process (the command you specify) and exits when that process terminates. There is no persistent operating system environment—just the isolated process execution.

## Lifecycle and Persistence

Persistence represents the most practical difference between these two approaches.

**Container machines** operate with a **persistent lifecycle**. Once created, a machine stays running until you explicitly stop or delete it. The filesystem, installed packages, and user data survive restarts. Data is stored in the machine's own persistent storage on disk, making it suitable for long-running development environments.

**Regular container instances** are **ephemeral** by default. They are created, run, and destroyed on demand. When the container stops, its state is discarded unless explicitly committed to an image or saved to external volumes. This makes them ideal for CI jobs, build steps, or microservices that should start fresh each time.

## User Experience and File System Mapping

Container machines offer seamless macOS integration that regular containers lack.

In a **container machine**, the host's macOS username and `$HOME` directory are automatically mounted inside the Linux VM at `/Users/<username>`. This enables seamless editing workflows where you modify code on macOS using native editors while building and testing inside the Linux environment. The home directory mapping requires no explicit volume mounts or configuration.

**Regular container instances** provide **no automatic user-home mapping**. If you need access to host files, you must explicitly mount volumes using flags like `--volume`. The container runs in isolation from the macOS host's user directory structure.

## Init System and Service Management

The presence of an init system enables fundamentally different capabilities.

**Container machines** start the image's init system (`/sbin/init`), allowing you to register and manage long-running services using standard Linux tools like `systemctl`. You can install daemons, configure autostart services, and manage the system like a traditional Linux server.

**Regular container instances** have **no init system**. The container executes only the command you provide and terminates when that command finishes. While you can run background processes, there is no service management framework or proper PID 1 handling.

## Resource Allocation and Configuration

Resource management differs significantly between the two models.

**Container machines** support dynamic resource resizing. You can modify CPU count, memory allocation, and home-mount configuration using the `container machine set` command. These changes persist to the machine's configuration file (defined in [`Sources/ContainerPersistence/MachineConfig.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/MachineConfig.swift)) and take effect after the next restart.

**Regular container instances** require resource specification at launch time using flags like `--cpus` and `--memory`. These resources cannot be reconfigured without stopping and recreating the container. There is no persistent configuration object for regular containers.

## Practical Usage Examples

### Working with Container Machines

Create a persistent development environment and manage it like a virtual machine:

```bash

# Create a persistent container machine (e.g., an Alpine VM)

container machine create alpine:latest --name dev

# Run commands inside the machine with automatic user/home mapping

container machine run -n dev whoami          # prints your macOS username

container machine run -n dev pwd             # shows /home/<you> inside the VM

# Open an interactive shell (state persists between sessions)

container machine run -n dev

# Resize resources (applies after next stop/start)

container machine set -n dev cpus=4 memory=8G
container machine stop dev
container machine run -n dev -- nproc       # verifies 4 CPUs

# Delete the machine and all its persistent storage

container machine rm dev

```

### Working with Regular Container Instances

Run isolated, short-lived application workloads:

```bash

# Create and run a short-lived container from an image

container run --name web --detach --rm nginx:latest

# Execute a single command inside the container

container exec web uname -a

# The container stops when killed; no persistent state remains

container stop web

```

## Implementation Details

The architectural differences are reflected in the source code implementation:

- **[`docs/container-machine.md`](https://github.com/apple/container/blob/main/docs/container-machine.md)**: User-facing documentation explaining the container-machine feature and its Linux environment model.

- **[`Sources/ContainerPersistence/MachineConfig.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/MachineConfig.swift)**: Defines the on-disk configuration for container machines, including CPU count, memory allocation, and home-mount settings that persist across restarts.

- **[`Sources/ContainerCommands/Container/ProcessUtils.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Container/ProcessUtils.swift)**: Implements the CLI subcommands that drive `container machine` operations (create, run, set, list), handling the persistent VM lifecycle.

- **[`Sources/ContainerXPC/XPCServer.swift`](https://github.com/apple/container/blob/main/Sources/ContainerXPC/XPCServer.swift)**: Handles XPC communication, launching a separate helper process for each container machine instance to maintain isolation and persistence.

- **[`Sources/ContainerPlugin/PluginLoader.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPlugin/PluginLoader.swift)**: Manages plugin instances per container machine, ensuring a single instance of each daemon runs within the persistent VM environment.

Regular containers are handled by the generic container runtime code in the same codebase, lacking the persistent configuration and XPC helper process architecture found in the machine implementation.

## Summary

- **Container machines** provide persistent Linux VMs with init systems, automatic macOS home directory mapping, and configurable resources that survive restarts.
- **Regular container instances** offer ephemeral, single-process isolation without persistence, requiring explicit volume mounts for host file access.
- **Source files** like [`MachineConfig.swift`](https://github.com/apple/container/blob/main/MachineConfig.swift) and [`ProcessUtils.swift`](https://github.com/apple/container/blob/main/ProcessUtils.swift) implement the persistent VM model, while regular containers use the generic runtime.
- **Use container machines** for development workflows requiring stable Linux environments; **use regular containers** for isolated application workloads and CI jobs.

## Frequently Asked Questions

### Can I convert a regular container instance into a container machine?

No, you cannot convert between the two. Container machines and regular container instances are fundamentally different architectures—a machine is a persistent VM with an init system, while a regular container is a single ephemeral process. To switch between models, you must create a new container machine from an image and migrate your data manually.

### How does the automatic home directory mapping work in container machines?

The `container` tool automatically mounts your macOS `$HOME` directory into the Linux VM at `/Users/<username>` when you run commands inside a machine. This is handled by the XPC server and configuration layer in [`Sources/ContainerXPC/XPCServer.swift`](https://github.com/apple/container/blob/main/Sources/ContainerXPC/XPCServer.swift) and [`Sources/ContainerPersistence/MachineConfig.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/MachineConfig.swift), ensuring your development files are accessible without explicit volume flags.

### Why would I choose a container machine over a regular container for development?

Choose a container machine when you need a persistent Linux environment that survives reboots, runs multiple services via an init system, and seamlessly integrates with your macOS home directory for editing. Regular containers are better suited for running isolated, stateless applications or one-shot commands that should not persist state between executions.

### Do container machines share resources with the host macOS system?

Container machines run in lightweight VMs with dedicated resources. You allocate specific CPU and memory limits using `container machine set`, and these resources are dedicated to the VM. Unlike regular containers, which share the host kernel, container machines provide stronger isolation through virtualization, though this incurs slightly higher overhead than the lightweight container runtime.