Apple Container Configuration File Structure: A Complete Guide to config.toml
Apple Container uses a layered TOML configuration file named config.toml that is searched in three locations—user home, app root, and install root—with settings merged in order of precedence and falling back to hard-coded defaults defined in ContainerSystemConfig.swift.
The open-source apple/container repository defines its runtime behavior through a hierarchical configuration system. The Apple Container configuration file follows the TOML format and supports layered overrides across user, application, and system directories, allowing developers to customize everything from builder VM resources to DNS domains and network subnets.
Configuration File Locations and Layered Precedence
Apple Container implements a first-match-wins precedence system that searches for config.toml in three distinct locations. The loader logic in Sources/ContainerPersistence/ConfigurationLoader.swift builds a layered snapshot from these paths, with earlier layers overriding later ones.
- User-home (
~/.config/container): The editable user configuration atconfig.tomltakes highest priority. - App-root (
…/config): A read-only copy atconfig/config.tomlused by the application at runtime. - Install-root (
/usr/local/etc/container): System-wide defaults shipped with the installation atetc/container/config.toml.
If a key is missing from every layer, the code defaults defined in Sources/ContainerPersistence/ContainerSystemConfig.swift are applied. If all files are absent, ConfigurationLoader.load() returns ContainerSystemConfig() containing the hard-coded defaults.
Top-Level Configuration Sections
The TOML schema is documented in docs/container-system-config.md. All top-level tables are optional; omitted sections fall back to the defaults defined in ContainerSystemConfig.swift.
[build] – Builder VM Resources
Controls the builder virtual machine settings for container builds.
rosetta:Bool(default:true) – Use Rosetta translation for non-native builds.cpus:Int(default:2) – CPU count for the builder VM.memory:MemorySize(default:"2048mb") – RAM allocated to the builder VM.image:String(default:ghcr.io/apple/container-builder-shim/builder:<tag>) – Builder image reference.
[container] – Per-Container Defaults
Defines default resource allocations for individual containers.
cpus:Int(default:4) – Default CPU count for a container.memory:MemorySize(default:"1g") – Default RAM for a container.
[dns] – DNS Domain Configuration
domain:String?(default: unset) – When set (e.g.,"test"), hostnames acquire this suffix (e.g.,my-web-server.test).
[kernel] – Guest Kernel Settings
binaryPath:String(default:"opt/kata/share/kata-containers/vmlinux-6.18.15-186") – Path inside the downloaded archive.url:URL(default:https://github.com/kata-containers/kata-containers/releases/download/3.28.0/kata-static-3.28.0-arm64.tar.zst) – Archive URL used if the kernel is not present locally.
[network] – Subnet Defaults
subnet:CIDRv4?(default: unset) – IPv4 CIDR (e.g.,"192.168.100.0/24").subnetv6:CIDRv6?(default: unset) – IPv6 CIDR (e.g.,"fd00:abcd::/64").
[registry] – Default Registry
domain:String(default:"docker.io") – Registry used when an image reference omits a host.
[vminit] – vminitd Image Configuration
image:String(default:ghcr.io/apple/containerization/vminit:<tag>) – Image for thevminitddaemon; the tag is derived from the bundled containerization version.
[plugin.] – Plugin-Scoped Configuration
Plugins may add their own tables under plugin.<id>. The plugin defines the schema; values are isolated per-plugin and scoped to the specific plugin ID.
Type Formats and Validation
The configuration system uses strongly-typed values beyond standard primitives.
MemorySize
Quoted strings with a numeric prefix and binary unit suffix (b, kb, mb, gb, tb, pb). Parsing is case-insensitive, and values are stored as binary amounts (powers of 1024). Example: "2048mb" or "4g". See Sources/ContainerPersistence/MemorySize.swift for the implementation details.
CIDRv4 and CIDRv6
Quoted strings containing standard CIDR notation. Examples: "192.168.100.0/24" for IPv4 or "fd00:abcd::/64" for IPv6.
How Configuration Loading Works
The loading process in ConfigurationLoader.swift follows a specific sequence to resolve the final configuration:
ConfigurationLoader.configurationFile(_:)builds the concreteFilePathfor the requested base (home, appRoot, or installRoot).load()creates aFileProvider<TOMLSnapshot>for each layer, allowing missing files to proceed without error.- The snapshots are merged with earlier layers overriding later ones.
ConfigSnapshotDecoderdecodes the merged snapshot intoContainerSystemConfig, which supplies the defaults defined in itsinit()methods.
This layered approach ensures that user-specific settings in ~/.config/container/config.toml override application defaults while maintaining system-wide fallbacks.
Configuration File Examples
Minimal User Configuration
Create ~/.config/container/config.toml to override specific defaults:
# User-only overrides – everything else uses library defaults.
[build]
cpus = 4
memory = "4g"
[container]
memory = "2g"
[dns]
domain = "test"
[registry]
domain = "myregistry.example.com"
Plugin-Specific Configuration
Plugins can receive their own configuration tables:
[plugin.mylogger]
logLevel = "debug"
output = "/var/log/container.log"
The plugin mylogger defines its own schema; the core loader scopes the TOML snapshot to plugin.mylogger.
Programmatic Access in Swift
Access the loaded configuration at runtime:
import ContainerPersistence
// Load the layered configuration (user config overrides system defaults)
let systemConfig = try await ConfigurationLoader.load()
print("Builder CPUs:", systemConfig.build.cpus) // → 4 (from example above)
print("Default DNS domain:", systemConfig.dns.domain ?? "none")
Summary
- Apple Container configuration file uses TOML format named
config.tomlwith layered loading from three locations. - Precedence order: User-home (
~/.config/container) overrides App-root, which overrides Install-root (/usr/local/etc/container). - Top-level sections include
[build],[container],[dns],[kernel],[network],[registry],[vminit], and[plugin.<id>]. - Special types
MemorySize,CIDRv4, andCIDRv6provide validated parsing for resources and networking. - Implementation resides in
ConfigurationLoader.swiftfor loading logic andContainerSystemConfig.swiftfor defaults and data models. - Fallback behavior: If all configuration files are absent, hard-coded defaults from
ContainerSystemConfig()are applied.
Frequently Asked Questions
Where does Apple Container look for the configuration file?
Apple Container searches three locations with first-match-wins precedence: the user home directory at ~/.config/container/config.toml, the application root at config/config.toml, and the installation root at /usr/local/etc/container/etc/container/config.toml. The search logic is implemented in Sources/ContainerPersistence/ConfigurationLoader.swift.
What format does the Apple Container configuration file use?
The configuration file uses TOML format. All top-level tables are optional, and the schema supports typed values including custom MemorySize strings (e.g., "2048mb") and CIDR notation for network subnets.
How are missing configuration keys handled?
If a key is missing from every configuration layer, the system falls back to hard-coded defaults defined in Sources/ContainerPersistence/ContainerSystemConfig.swift. If no configuration files exist at any layer, ConfigurationLoader.load() returns ContainerSystemConfig() initialized with these code defaults.
Can plugins define their own configuration sections?
Yes. Plugins can add custom tables under [plugin.<id>] where <id> is the plugin identifier. The plugin defines its own schema for values within that table, and the core configuration loader isolates these values per-plugin without enforcing a specific structure.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →