Configuring System Properties and Managing Kernels for Containers in Apple Container

The Apple container repository uses a declarative TOML file (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, 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 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 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 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, 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:

[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 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:

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:

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.
  • 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 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. 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 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 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 require a restart of the container daemon to take effect. This immutability guarantee ensures thread-safe access to configuration values throughout the system lifecycle.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →