# How to Start the Container System Services Using the CLI

> Learn to start the container system services using the CLI with the container system start command. Initialize daemons, verify health, and install kernel assets effortlessly.

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

---

**`container system start`** is the CLI command that initializes and registers the core Container background services with macOS launchd, verifies daemon health, and optionally installs default kernel assets.

The `apple/container` repository provides a macOS-native container runtime. To begin using containers, you must first start the container system services using the CLI, which configures the background daemon and prepares the runtime environment.

## What Happens When You Run `container system start`

When executed, the command performs a coordinated sequence of initialization steps defined in [`Sources/ContainerCommands/System/SystemStart.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/System/SystemStart.swift).

### Configuration Loading

The command begins by invoking `ConfigurationLoader.load` to read application and install configuration files. It searches for these files in standard locations, using a first-match-wins strategy to determine the active configuration (lines 82-86).

### Launch Daemon Preparation

Next, the CLI constructs a `LaunchPlist` pointing to the `container-apiserver` binary. This plist restricts the service to specific session types—**Aqua**, **Background**, and **System**—and injects critical environment variables including `CONTAINER_APP_ROOT`, `CONTAINER_INSTALL_ROOT`, and optionally `CONTAINER_LOG_ROOT` (lines 15-22).

### Service Registration with launchd

Using `ServiceManager.register(plistPath:)`, the command writes the plist to `<appRoot>/apiserver/apiserver.plist` and instructs launchd to load the service. This registers the `container-apiserver` as a persistent background process (lines 24-31).

### Health Verification

After registration, the CLI validates the daemon is responsive. It executes `ClientHealthCheck.ping` against the API server and calls `MachineClient().list()` to verify the machine API is accessible. If either check fails, the command aborts with a descriptive `ContainerizationError` (lines 33-46).

### Asset Installation

Finally, the command ensures runtime assets are present. If the initial filesystem image is missing, `installInitialFilesystem` pulls it. If no kernel exists, `installDefaultKernel` optionally downloads the recommended kernel, respecting the `--enable-kernel-install` or `--disable-kernel-install` flags (lines 52-61).

## CLI Usage Examples

Start the container services with default directories:

```bash
container system start

```

Customize the root directories:

```bash
container system start \
  --app-root $HOME/.config/container \
  --install-root /usr/local/Cellar/container \
  --log-root $HOME/Library/Logs/container

```

Install the default kernel automatically without prompting:

```bash
container system start --enable-kernel-install

```

Skip kernel installation when using your own kernel:

```bash
container system start --disable-kernel-install

```

## Verification and Next Steps

After starting services, verify the system is operational:

```bash

# Check daemon status

container system status

# List containers (empty initially)

container list

# Run your first container

container run --name hello hello-world

```

The `container system status` command reports whether the daemon is running and displays its PID, confirming successful registration with launchd.

## Key Implementation Files

The startup logic resides in two primary Swift files within the `apple/container` repository:

- **[`Sources/ContainerCommands/System/SystemCommand.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/System/SystemCommand.swift)**: Defines the `system` command group structure and registers subcommands including `start`, `stop`, `status`, and `logs` (lines 20-38).
- **[`Sources/ContainerCommands/System/SystemStart.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/System/SystemStart.swift)**: Implements the `SystemStart` class containing the full initialization sequence, from configuration loading to health checks.

## Summary

- **`container system start`** is the entry point for initializing the macOS container runtime.
- The command loads configuration via `ConfigurationLoader.load`, prepares a `LaunchPlist` for the `container-apiserver` binary, and registers it with launchd using `ServiceManager.register(plistPath:)`.
- Health verification uses `ClientHealthCheck.ping` and `MachineClient().list()` to ensure the daemon is responsive before completing.
- Optional flags `--enable-kernel-install` and `--disable-kernel-install` control whether the CLI downloads default kernel assets automatically.
- Source code is located in [`Sources/ContainerCommands/System/SystemStart.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/System/SystemStart.swift) within the `apple/container` repository.

## Frequently Asked Questions

### What is the exact command to start container services?

The exact command is **`container system start`**. This subcommand, defined in [`Sources/ContainerCommands/System/SystemStart.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/System/SystemStart.swift), coordinates the entire bootstrap process including launchd registration and health verification.

### How does the CLI verify the daemon is running?

After registering with launchd, the CLI performs two health checks: it sends a `ClientHealthCheck.ping` to the API server and executes `MachineClient().list()` to confirm the machine API responds. Failure of either check raises a `ContainerizationError` and aborts the startup sequence.

### Can I start the services without installing the default kernel?

Yes. Pass the `--disable-kernel-install` flag to skip automatic kernel downloads. This is useful when you have already installed a custom kernel or prefer to manage kernel assets manually.

### Where does the CLI store the launchd plist file?

The CLI writes the launchd plist to `<appRoot>/apiserver/apiserver.plist` within your configured application root directory. This path is determined by the `CONTAINER_APP_ROOT` environment variable or the `--app-root` CLI flag.