# How to Create a Container Using Apple's Container Runtime: CLI and Swift Guide

> Learn to create a container using Apple's container runtime. Explore the CLI create command and Swift RuntimeClient for easy sandbox bootstrapping.

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

---

**To create a container using Apple's container runtime, use the `container create` command to generate a runtime configuration and VM bundle without starting the process, or instantiate a `RuntimeClient` in Swift to bootstrap the sandbox via XPC.**

The **apple/container** repository provides a lightweight container runtime that runs Linux containers as virtual machines (VMs) on macOS using the Virtualization framework. When you create a container, the runtime builds a persistent bundle and establishes a sandboxed environment, keeping the container in a "created" state until you explicitly start it. This design allows you to inspect, configure, and modify container resources before any user process executes.

## Understanding the Container Creation Architecture

Creating a container using Apple's runtime involves a multi-step flow that separates environment setup from process execution. The architecture leverages XPC services for secure communication between the CLI and the backend runtime.

The creation flow follows these steps:

1. **CLI request parsing** – The `container create` command, documented in [`docs/command-reference.md`](https://github.com/apple/container/blob/main/docs/command-reference.md), collects user-specified options like CPU count, memory limits, and volume mounts.
2. **Runtime configuration generation** – [`ContainersService.swift`](https://github.com/apple/container/blob/main/ContainersService.swift) constructs a `RuntimeConfiguration` object containing the VM bundle path, kernel image, filesystem layers, and network settings.
3. **XPC service connection** – The `RuntimeClient.create(id:runtime:)` method in [`RuntimeClient.swift`](https://github.com/apple/container/blob/main/RuntimeClient.swift) establishes a connection to `com.apple.container.runtime.<runtime>.<id>`.
4. **Sandbox bootstrap** – The client sends a `bootstrap` request to the runtime service, which launches a macOS Virtualization framework VM and prepares the root filesystem.
5. **Persistent state** – The container receives a unique ID and stores its configuration on disk, remaining in a created (stopped) state until started.

This separation of creation and startup allows you to use `container inspect` to review the configuration or adjust mounts before the container runs.

## Creating Containers from the Command Line

### Basic Syntax and Key Options

The `container create` command generates a VM-based sandbox without immediately executing a containerized process. According to the command reference in [`docs/command-reference.md`](https://github.com/apple/container/blob/main/docs/command-reference.md), you can specify resource constraints and runtime behavior using these key options:

- `--name <name>` – Assign a human-readable identifier that serves as the container ID.
- `--cpu <cpus>` – Allocate a specific number of virtual CPUs to the VM.
- `--memory <memory>` – Set RAM allocation (e.g., `2G` for 2 gigabytes).
- `--runtime <runtime>` – Select a runtime plugin; defaults to `container-runtime-linux`.
- `--init` – Enable an init process that handles signal forwarding and zombie reaping.
- `--volume <volume>` – Bind-mount host directories or named volumes into the container.
- `--publish <spec>` – Map container ports to the host system.

### Practical CLI Examples

Create a container named "my-app" with specific resource constraints:

```bash

# Create a container from the Ubuntu image with 2GB RAM and 2 CPUs

container create \
    --name my-app \
    --memory 2G \
    --cpu 2 \
    ubuntu:latest

```

This command outputs a unique container ID (e.g., `a1b2c3d4e5f6`) and stores the VM bundle on disk. The container exists in a stopped state, ready for inspection or modification.

Start the created container later:

```bash
container start my-app

```

Alternatively, combine creation and startup in one step using `container run`, though this bypasses the ability to inspect the sandbox beforehand.

## Creating Containers Programmatically with Swift

For applications requiring direct integration with the container runtime, you can create containers programmatically using the Swift APIs provided in the `Sources/Services/Runtime/RuntimeClient/` directory.

### Building the Runtime Configuration

First, construct a `RuntimeConfiguration` object that describes the VM environment. This mirrors the configuration generation performed by [`ContainersService.swift`](https://github.com/apple/container/blob/main/ContainersService.swift) when processing CLI requests:

```swift
import Container

// Configure the VM bundle and filesystem
let runtimeConfig = RuntimeConfiguration(
    path: URL(fileURLWithPath: "/tmp/container-bundle"),
    initialFilesystem: "ubuntu:latest",
    kernel: nil,
    containerConfiguration: nil,
    containerRootFilesystem: nil,
    options: nil
)

// Serialize to JSON for the runtime service
try runtimeConfig.writeRuntimeConfiguration()

```

The `RuntimeConfiguration` struct, defined in [`Sources/Services/Runtime/RuntimeClient/RuntimeConfiguration.swift`](https://github.com/apple/container/blob/main/Sources/Services/Runtime/RuntimeClient/RuntimeConfiguration.swift), handles JSON serialization and validates the bundle structure before the XPC connection occurs.

### Bootstrapping via the RuntimeClient

After configuring the environment, establish an XPC connection and bootstrap the sandbox:

```swift
// Initialize the XPC client for the Linux runtime
let client = try await RuntimeClient.create(
    id: "swift-example",
    runtime: "container-runtime-linux"
)

// Bootstrap the VM without starting a user process
await client.bootstrap(
    stdio: .inherit,
    networkBootstrapInfos: [],
    dynamicEnv: [:]
)

```

The `RuntimeClient.create(id:runtime:)` method, implemented in [`Sources/Services/Runtime/RuntimeClient/RuntimeClient.swift`](https://github.com/apple/container/blob/main/Sources/Services/Runtime/RuntimeClient/RuntimeClient.swift), creates the XPC endpoint. The `bootstrap` method launches the Virtualization framework VM and prepares the root filesystem, leaving the container ready for a subsequent `client.start(...)` call.

## Verifying and Managing Created Containers

Once created, containers persist on disk with their configuration files and VM bundles. Verify the creation status using the following commands:

```bash

# List all containers, including created but not running

container ls

# Inspect detailed configuration including bundle path and resources

container inspect my-app

```

The `container inspect` command outputs JSON containing the runtime configuration, mount points, and network settings defined during creation. This allows you to confirm that [`Sources/Services/ContainerAPIService/Server/Containers/ContainersService.swift`](https://github.com/apple/container/blob/main/Sources/Services/ContainerAPIService/Server/Containers/ContainersService.swift) correctly processed your resource limits and volume mounts before starting the container.

## Summary

- **Apple's container runtime** runs Linux containers as lightweight VMs on macOS using the Virtualization framework.
- **Creation vs. Execution** – The `container create` command and `RuntimeClient.bootstrap` method establish the sandbox without starting a user process, allowing pre-execution configuration.
- **Key Implementation Files** – Container creation logic resides in [`ContainersService.swift`](https://github.com/apple/container/blob/main/ContainersService.swift), XPC client communication in [`RuntimeClient.swift`](https://github.com/apple/container/blob/main/RuntimeClient.swift), and configuration serialization in [`RuntimeConfiguration.swift`](https://github.com/apple/container/blob/main/RuntimeConfiguration.swift).
- **CLI Options** – Specify resources using `--cpu`, `--memory`, and `--volume` flags documented in [`docs/command-reference.md`](https://github.com/apple/container/blob/main/docs/command-reference.md).
- **Programmatic Access** – Use `RuntimeConfiguration` and `RuntimeClient` Swift APIs to integrate container creation into macOS applications.

## Frequently Asked Questions

### What is the difference between `container create` and `container run`?

`container create` generates a runtime configuration and VM bundle but leaves the container in a stopped state, allowing you to inspect or modify it before execution. `container run` combines creation and startup, immediately executing the containerized process without an intermediate inspection phase.

### Where does Apple's container runtime store VM bundles and configuration?

The runtime stores container bundles in a directory specified by the `RuntimeConfiguration.path` property, typically within the macOS temporary directory or a user-specified location. The `container inspect` command reveals the exact bundle path and serialized JSON configuration for each container ID.

### Can I create containers without using the command-line interface?

Yes, you can create containers programmatically by importing the Container framework and using `RuntimeClient.create(id:runtime:)` to establish an XPC connection to `com.apple.container.runtime.<runtime>.<id>`, then calling `bootstrap` to initialize the VM sandbox. This approach is implemented in [`Sources/Services/Runtime/RuntimeClient/RuntimeClient.swift`](https://github.com/apple/container/blob/main/Sources/Services/Runtime/RuntimeClient/RuntimeClient.swift).

### Why does the container runtime use XPC services for container creation?

The XPC architecture isolates the privileged Virtualization framework operations in a separate service process (`container-runtime-linux`), enhancing security by restricting the CLI's access to low-level VM management. The `RuntimeClient` in the CLI communicates with this service to request VM creation and resource allocation.