How to Configure Network Subnets and MAC Addresses for Containers in apple/container
Use the --subnet and --subnet-v6 flags when creating a network to define IPv4/IPv6 CIDR ranges, and specify a custom MAC address with the --mac-address flag when running or creating a container.
The apple/container runtime provides precise control over container networking through CLI flags that map directly to underlying Swift structs. Whether you need to isolate workloads with custom IP ranges or enforce deterministic MAC addresses for DHCP reservations, you can configure network subnets and MAC addresses for containers using straightforward command options that populate NetworkConfiguration and AttachmentOptions types.
Defining Network Subnets with network create
When you create a network, the CLI accepts optional flags to specify the IP address space. These values are transformed into CIDRv4 and CIDRv6 types and stored in the NetworkConfiguration struct defined in Sources/ContainerResource/Network/NetworkConfiguration.swift.
IPv4 Subnet Configuration (--subnet)
The --subnet flag accepts an IPv4 CIDR notation (e.g., 10.0.0.0/24). According to the source code in Sources/ContainerCommands/Network/NetworkCreate.swift, this flag maps to the ipv4Subnet property of NetworkConfiguration.
The flag is defined as an @Option with a custom transform that validates the input:
@Option(
name: .customLong("subnet"),
help: "Set subnet for a network",
transform: { try CIDRv4($0) })
var ipv4Subnet: CIDRv4? = nil
When the command executes (lines 69–76 of NetworkCreate.swift), it instantiates a NetworkConfiguration with the parsed value and passes it to the NetworkClient, which forwards the configuration to the network plugin.
IPv6 Subnet Configuration (--subnet-v6)
Similarly, the --subnet-v6 flag accepts an IPv6 prefix (e.g., fd01::/48). This maps to NetworkConfiguration.ipv6Subnet in the same source files. The CLI validates the input using the CIDRv6 type before storing it in the configuration model.
Assigning MAC Addresses to Container Attachments
You can assign a specific MAC address to a container's network interface during container creation. The runtime stores this value in an AttachmentOptions struct and transmits it via XPC to the network service.
Using the --mac-address Flag
When running container run or container create, include the --mac-address option followed by a valid MAC address (e.g., 02:42:ac:11:00:02). The CLI parses this string into a MACAddress value and stores it in the AttachmentOptions struct defined in Sources/ContainerResource/Network/Attachment.swift.
Internal Flow to the Network Service
The NetworkClient.createAttachment method (in Sources/Services/Network/Client/NetworkClient.swift) adds the MAC address to the XPC request using the NetworkKeys.macAddress key defined in Sources/Services/Network/Client/NetworkKeys.swift.
On the runtime side, DefaultNetworkService (in Sources/Services/Network/Server/DefaultNetworkService.swift) receives the request. If you provide a MAC address, the service uses that value; if omitted, it generates a deterministic MAC address automatically.
Complete Configuration Examples
The following examples demonstrate how to configure network subnets and MAC addresses for containers using the apple/container CLI.
Create a network with custom IPv4 and IPv6 subnets:
container network create mynet \
--subnet 10.0.0.0/24 \
--subnet-v6 fd01::/48
Run a container on that network with a specific MAC address:
container run -d \
--name myapp \
--network mynet \
--mac-address 02:42:ac:11:00:02 \
docker.io/library/nginx:latest
Under the hood, the CLI constructs these Swift types:
let config = try NetworkConfiguration(
name: "mynet",
mode: .nat,
ipv4Subnet: try CIDRv4("10.0.0.0/24"),
ipv6Subnet: try CIDRv6("fd01::/48"),
labels: .init(),
plugin: "container-network-vmnet",
options: [:]
)
let attachment = AttachmentOptions(
hostname: "myapp",
macAddress: try MACAddress("02:42:ac:11:00:02"),
mtu: nil
)
Summary
- Use
--subnetwithnetwork createto define IPv4 CIDR ranges that map toNetworkConfiguration.ipv4SubnetinSources/ContainerResource/Network/NetworkConfiguration.swift. - Use
--subnet-v6to specify IPv6 prefixes stored inNetworkConfiguration.ipv6Subnet. - Use
--mac-addresswithcontainer runorcreateto set a deterministic MAC address, parsed intoAttachmentOptionsand sent viaNetworkClientusing theNetworkKeys.macAddresskey. - The runtime validates CIDR formats during parsing via
CIDRv4andCIDRv6transforms, and handles MAC address assignment inDefaultNetworkService, generating one automatically if not provided.
Frequently Asked Questions
What CIDR formats does apple/container support for subnet configuration?
The runtime accepts standard IPv4 CIDR notation (e.g., 192.168.1.0/24) for the --subnet flag and IPv6 prefix notation (e.g., fd00::/64) for the --subnet-v6 flag. The CLI transforms these strings into strong types CIDRv4 and CIDRv6 during the parsing phase in NetworkCreate.swift.
Can I change a container's MAC address after it is running?
No, the MAC address is configured during the attachment creation phase. The NetworkClient.createAttachment method transmits the MAC address via XPC when the container starts, and DefaultNetworkService binds it to the interface at that time. To change the MAC address, you must recreate the container with the --mac-address flag.
How does the runtime handle MAC address collisions?
According to the implementation in Sources/Services/Network/Server/DefaultNetworkService.swift, if you do not specify a MAC address, the runtime generates a deterministic address based on the container configuration. If you provide a custom MAC address, the runtime uses that exact value. You should ensure uniqueness manually when assigning specific addresses, as the runtime does not perform collision detection against other manually assigned addresses.
Where is the network subnet configuration stored?
The subnet definitions reside in the NetworkConfiguration struct (defined in Sources/ContainerResource/Network/NetworkConfiguration.swift). When you create a network, the CLI builds this struct and passes it to the NetworkClient, which persists the configuration through the network plugin specified in the plugin property (typically container-network-vmnet).
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 →