# container-apiserver: Orchestrating Container Lifecycles on macOS

> Discover how container-apiserver orchestrates container lifecycles on macOS. This central API server manages container creation, startup, stopping, inspection, and deletion via XPC services.

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

---

**container-apiserver is the central API server that exposes XPC-based services to create, start, stop, inspect, and delete containers, serving as the primary orchestrator for macOS container lifecycle management.**

The `container-apiserver` is the backbone of Apple's open-source [apple/container](https://github.com/apple/container) repository, running as a system-level launch daemon that bridges CLI commands with kernel-level container operations. This Swift-based service handles everything from sandbox allocation to network configuration, ensuring reliable container lifecycle management across macOS systems.

## XPC Server Architecture and Route Registration

At the core of the container-apiserver is an XPC (Inter-Process Communication) server that exposes container lifecycle operations to clients. The server registers route handlers that map incoming XPC calls to specific service harnesses responsible for containers, networks, volumes, and health checks.

The binary entry point is defined in **[`Sources/APIServer/APIServer.swift`](https://github.com/apple/container/blob/main/Sources/APIServer/APIServer.swift)**, where the `main` function declares the command name and version through a `CommandConfiguration`. When the server starts, it executes the start sub-command defined in **`Sources/APIServer/APIServer+Start.swift`**.

In `APIServer+Start.swift`, the `XPCServer` is instantiated with the Mach service identifier `com.apple.container.apiserver` and a dictionary of route handlers. These routes map specific XPC calls—such as `containerCreate`, `containerStartProcess`, `containerStop`, and `containerDelete`—to their corresponding harness implementations:

```swift
// Excerpt from Sources/APIServer/APIServer+Start.swift
routes[XPCRoute.containerCreate] = XPCServer.route(ContainersHarness.create)
routes[XPCRoute.containerStartProcess] = XPCServer.route(ContainersHarness.startProcess)
routes[XPCRoute.containerStop] = XPCServer.route(ContainersHarness.stop)
routes[XPCRoute.containerDelete] = XPCServer.route(ContainersHarness.delete)

```

## Container Lifecycle Operations

The **[`Sources/Services/ContainerAPIService/Server/Containers/ContainersHarness.swift`](https://github.com/apple/container/blob/main/Sources/Services/ContainerAPIService/Server/Containers/ContainersHarness.swift)** file implements the concrete handlers for container lifecycle management. Each harness method delegates to underlying service implementations that interact with the macOS sandbox and kernel extensions.

When a client invokes `container create`, the server allocates a sandbox, mounts volumes, configures networking, and persists the configuration via `ContainerPersistence` components. The `ContainersHarness` coordinates these resources before returning the container ID to the caller.

Process execution flows through `containerStartProcess`, which manages the actual runtime inside the container, including I/O handling and CPU/memory accounting. Graceful teardown occurs via `containerStop` and `containerDelete`, which trigger resource cleanup, network de-registration, and persistent state removal.

## System Integration and Health Monitoring

The container-apiserver integrates deeply with macOS system services through launch daemon registration. In **[`Sources/ContainerCommands/System/SystemStart.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/System/SystemStart.swift)**, the server generates a launch-daemon plist (`apiserver.plist`) that registers the Mach service name `com.apple.container.apiserver` and configures the daemon to start automatically.

Health monitoring is implemented in **[`Sources/Services/ContainerAPIService/Server/HealthCheck/HealthCheckHarness.swift`](https://github.com/apple/container/blob/main/Sources/Services/ContainerAPIService/Server/HealthCheck/HealthCheckHarness.swift)**. This harness populates health-check replies with metadata including `apiServerVersion`, `apiServerAppName`, and build information, which the `container system status` command surfaces to users:

```bash

# Query the server's health-check endpoint

$ container system status
apiserver.version   1.2.3
apiserver.commit    abcdef1
apiserver.build     2024-08-15
apiserver.appName   container-apiserver

```

## Networking and Plugin System Initialization

Before accepting container operations, the server initializes a plugin system via `initializePluginLoader`, which discovers built-in and user-installed plugins. Plugins declaring `shouldBoot = true` are loaded immediately and can extend the API surface or provide custom resources, such as the `container-network-vmnet` plugin for NAT networking.

DNS resolution is handled by two specialized resolvers—one for container hostnames and one for localhost—started during server initialization in `APIServer+Start.swift`. These resolvers feed into the container-wide DNS stack, ensuring proper name resolution within isolated network namespaces.

## Summary

- **container-apiserver** runs as the launch daemon `com.apple.container.apiserver` and serves as the central API server for macOS container lifecycle management.
- The XPC server in `APIServer+Start.swift` registers route handlers that map calls like `containerCreate` and `containerStop` to harnesses in [`ContainersHarness.swift`](https://github.com/apple/container/blob/main/ContainersHarness.swift).
- **System integration** occurs through [`SystemStart.swift`](https://github.com/apple/container/blob/main/SystemStart.swift), which creates the launch-daemon plist and registers the Mach service for automatic startup.
- **Health monitoring** via [`HealthCheckHarness.swift`](https://github.com/apple/container/blob/main/HealthCheckHarness.swift) exposes version and build metadata through the `container system status` command.
- **Plugin support** allows extending container capabilities, with built-in plugins providing networking features like NAT via `container-network-vmnet`.

## Frequently Asked Questions

### How does container-apiserver communicate with client CLI tools?

Client CLI tools communicate with container-apiserver via XPC (Inter-Process Communication) calls. The CLI acts as a thin wrapper that forwards commands like `container create` or `container stop` to the XPC server running as `com.apple.container.apiserver`, which then routes the requests to the appropriate service harnesses.

### Where is the container state persisted across daemon restarts?

The server works with `ContainerPersistence` components to load and store container, network, and volume configurations on disk. This persistent state ensures that container definitions survive daemon restarts and system reboots, with data managed through the service harnesses in coordination with the API server.

### What information does the health-check endpoint provide?

The `HealthCheckHarness` populates replies containing `apiServerVersion`, `apiServerAppName`, `apiServerCommit`, and build dates. This metadata is surfaced through the `container system status` command and allows clients to verify compatibility and deployment versions with the running daemon.

### Can container-apiserver be started manually for debugging?

While normally started by `launchd` automatically, you can invoke the binary directly for debugging or development purposes using the start sub-command. The server will initialize the XPC listener, register all service routes, and begin accepting connections until terminated:

```bash

# Start the API server manually

$ container-apiserver start

```