# Configuring System Properties and Managing Kernels for Containers in Apple Container

> Learn to configure system properties and manage kernels for containers using Apple's declarative config.toml. Automatically download guest kernels for seamless container management.

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

---

**The Apple container repository uses a declarative TOML file ([`config.toml`](https://github.com/apple/container/blob/main/config.toml)) parsed by the `ContainerSystemConfig` Swift class to manage system-wide properties including guest kernels, which are automatically downloaded from remote archives when missing locally.**

The Apple container repository provides a declarative approach to **configuring system properties and managing kernels for containers** through a centralized TOML configuration system. By modifying [`config.toml`](https://github.com/apple/container/blob/main/config.toml), operators control VM-based container behavior—from memory allocation to guest kernel versions—without recompiling the runtime. This configuration-driven architecture ensures that the system applies consistent defaults while supporting explicit overrides for specialized workloads.

## Configuration Architecture Overview

The configuration system spans three layers: the TOML schema definition, the Swift model implementation, and runtime resolution. At the top level, [`docs/container-system-config.md`](https://github.com/apple/container/blob/main/docs/container-system-config.md) documents the supported sections and type formats, serving as the single source of truth for users.

The `ContainerSystemConfig` class defined in [`Sources/ContainerPersistence/ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/ContainerSystemConfig.swift) aggregates eight sub-configurations: `BuildConfig`, `ContainerConfig`, `DNSConfig`, `KernelConfig`, `MachineConfig`, `NetworkConfig`, `RegistryConfig`, and `VMInitConfig`. Each sub-configuration implements `Codable` and provides static default constants that apply when TOML fields are omitted.

Type-safe parsing occurs through custom decoders in `Sources/ContainerPersistence/Measurement+Parse.swift`, which enforce binary-unit conventions for memory sizes and validate CIDR notation for network addresses. Values that depend on shipped binaries—such as those resolved by `get_container_builder_shim_version()` and `get_swift_containerization_version()`—are determined at runtime rather than compile time. The TOML decoder transforms the raw file into immutable Swift structs, ensuring thread-safe access after initial loading.

## Kernel Management Configuration

The `[kernel]` section within [`config.toml`](https://github.com/apple/container/blob/main/config.toml) controls the guest kernel used by VM-based containers. This configuration determines which kernel binary to load and where to fetch it if missing from the local filesystem.

### Default Kernel Settings

By default, the system expects the kernel binary at a specific path inside a downloaded KATA archive. The `KernelConfig` struct specifies:

- **binaryPath**: `"opt/kata/share/kata-containers/vmlinux-6.18.15-186"` — the relative path inside the extracted archive pointing to the actual kernel binary
- **url**: `https://github.com/kata-containers/kata-containers/releases/download/3.28.0/kata-static-3.28.0-arm64.tar.zst` — the remote archive fetched automatically when the kernel is absent

These defaults are hard-coded as static constants in [`ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/ContainerSystemConfig.swift), though runtime-dependent values are resolved dynamically. The `url` field is stored as a plain string in TOML for cross-format compatibility, then normalized to a `URL` type internally by the Swift model.

### Customizing Kernel Sources

To override the default kernel, modify the `[kernel]` section in [`/etc/container/config.toml`](https://github.com/apple/container/blob/main//etc/container/config.toml):

```toml
[kernel]
binaryPath = "opt/kata/share/kata-containers/vmlinux-6.20.0-200"
url = "https://github.com/kata-containers/kata-containers/releases/download/3.30.0/kata-static-3.30.0-arm64.tar.zst"

```

When the daemon starts, it validates the existence of the file at `binaryPath`. If absent, it triggers a download from the specified `url`, extracts the archive, and uses the binary for subsequent container operations. The CI helper script [`scripts/update-container.sh`](https://github.com/apple/container/blob/main/scripts/update-container.sh) automates this fetch process during release builds.

## Loading and Modifying Configuration

The container daemon and CLI tools interact with the configuration through Swift's `Codable` protocol, enabling type-safe access to all system properties.

### Decoding config.toml in Swift

To load the system configuration programmatically, use the `TOMLDecoder` provided by the project:

```swift
import Foundation
import ContainerPersistence

let configURL = URL(fileURLWithPath: "/etc/container/config.toml")
do {
    let data = try Data(contentsOf: configURL)
    let decoder = TOMLDecoder()
    let systemConfig = try decoder.decode(
        ContainerSystemConfig.self,
        from: data
    )
    
    print("Kernel binary:", systemConfig.kernel.binaryPath)
    print("Kernel URL:", systemConfig.kernel.url)
} catch {
    print("Configuration failed to load: \(error)")
}

```

This pattern reads the TOML file into the `ContainerSystemConfig` aggregate type, automatically applying default values for any omitted sections.

### Overriding Kernel Paths Programmatically

For tooling that needs to inject kernel settings at runtime—such as testing newer kernel builds—construct a modified configuration instance:

```swift
var systemConfig = try decoder.decode(ContainerSystemConfig.self, from: data)

systemConfig = ContainerSystemConfig(
    kernel: KernelConfig(
        binaryPath: "/custom/kata/vmlinux",
        url: URL(string: "https://example.com/custom-kata.tar.zst")!
    ),
    build: systemConfig.build,
    container: systemConfig.container,
    dns: systemConfig.dns,
    machine: systemConfig.machine,
    network: systemConfig.network,
    registry: systemConfig.registry,
    vminit: systemConfig.vminit
)

```

This approach preserves existing configuration sections while replacing only the kernel parameters, useful for CI pipelines or development workflows that require specific kernel versions.

## Summary

- The Apple container runtime uses a TOML-based configuration system centered on the `ContainerSystemConfig` class in [`Sources/ContainerPersistence/ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/ContainerSystemConfig.swift).
- System properties are organized into eight sub-configurations, with the `[kernel]` section controlling guest kernel binaries and download sources.
- Default kernels point to specific paths within KATA archives downloaded from GitHub releases, with automatic fetch-on-missing behavior.
- Configuration parsing uses custom `Codable` implementations and `Measurement+Parse.swift` for type-safe validation of memory and network values.
- Operators can override kernel settings via [`config.toml`](https://github.com/apple/container/blob/main/config.toml) edits or programmatically through Swift struct initialization.

## Frequently Asked Questions

### Where is the system configuration file located?

The container daemon expects the configuration file at [`/etc/container/config.toml`](https://github.com/apple/container/blob/main//etc/container/config.toml). This path contains the TOML definitions for all system properties including kernel, network, and build settings. The file follows the schema documented in [`docs/container-system-config.md`](https://github.com/apple/container/blob/main/docs/container-system-config.md) within the repository.

### What happens if the kernel binary is missing at runtime?

When the daemon starts with a `binaryPath` pointing to a non-existent file, it automatically downloads the archive specified by the `url` field, extracts the contents, and locates the kernel binary within the extracted directory. This ensures that fresh installations or updates can bootstrap the required kernel without manual intervention.

### How do I specify a custom kernel version for testing?

Create a custom `[kernel]` section in your [`config.toml`](https://github.com/apple/container/blob/main/config.toml) with the `binaryPath` pointing to your test kernel location inside the archive structure and the `url` pointing to your custom archive. Alternatively, programmatically construct a `KernelConfig` instance with your custom paths and pass it to the `ContainerSystemConfig` initializer, keeping other configuration sections unchanged.

### Are configuration changes applied immediately or require a restart?

The configuration is immutable after decoding and loaded at daemon startup. Changes to [`config.toml`](https://github.com/apple/container/blob/main/config.toml) require a restart of the container daemon to take effect. This immutability guarantee ensures thread-safe access to configuration values throughout the system lifecycle.