How to Manage Container Networks on macOS Using Apple's Runtime
Apple's container runtime isolates each container in a lightweight Linux VM and uses the vmnet framework via the XPC helper container-network-vmnet to create NAT bridges, allocate subnets, and manage network connectivity.
The apple/container repository provides a native container runtime for macOS that runs containers inside isolated Linux virtual machines. To enable network connectivity for these VMs, the runtime implements a specialized network plugin that interfaces with the macOS kernel extension. This article explains how to create, configure, and manage container networks using the Apple container runtime's CLI and underlying architecture.
Architecture of Container Networking on macOS
Apple's container runtime implements a multi-process architecture where networking is handled by a dedicated XPC service. When you start the container system, the container-apiserver launches three helper processes: container-core-images for image management, container-runtime-linux for the per-container runtime API, and container-network-vmnet for virtual network management.
The XPC Helper and Plugin System
The container-network-vmnet binary acts as the XPC entry point for all network operations. Implemented in Sources/Plugins/NetworkVmnet/NetworkVmnetHelper.swift, this helper registers the NetworkVmnet plugin (default name container-network-vmnet) and parses subcommands from the main CLI. The helper translates high-level network commands into low-level system calls to the macOS vmnet framework.
The vmnet Framework Integration
The vmnet framework creates a NAT bridge that connects container VMs to the host network. When you create a network, the helper allocates a subnet, assigns a bridge identifier, and reserves IP addresses for future container attachments. This integration is only available on macOS 26+, which ships with the new vmnet APIs required for multiple network support. On macOS 15, the framework only supports a single default network, and the container network commands are disabled.
Creating and Managing Networks
Network operations require the container system to be running. The CLI commands delegate to the XPC helper, which stores network definitions in the container-system state as defined in Sources/ContainerResource/Network/NetworkConfiguration.swift.
Starting the Container System
Before creating networks, you must start the system daemon that manages the XPC helpers:
container system start
This command launches container-apiserver, which in turn spawns the container-network-vmnet helper process.
Creating Custom Networks
Create isolated networks with specific subnets using the container network create command. The implementation in Sources/ContainerCommands/Network/NetworkCreate.swift propagates flags like --subnet and --plugin to the XPC helper:
# Create a network named "frontend" with a custom IPv4 subnet
container network create \
--subnet 192.168.200.0/24 \
frontend
The helper creates a vmnet bridge named com.apple.container.network.frontend and stores the configuration including the subnet allocation.
Listing and Inspecting Networks
View all configured networks using the list command:
container network list
Example output:
NAME DRIVER SUBNET
frontend vmnet 192.168.200.0/24
default vmnet 192.168.64.0/24
For detailed information about a specific network, including the bridge ID, subnet, attached containers, and plugin configuration, use:
container network inspect frontend
Attaching Containers to Networks
When launching containers, you can specify which network to attach or use the default network automatically.
Running Containers with Specific Networks
Use the --network flag to attach a container to a specific network:
container run -d \
--name web \
--network frontend \
nginx:latest
The container-runtime-linux process requests an IP allocation from the network helper, which configures a tap device attached to the VM.
Configuring MAC Addresses
You can specify a static MAC address when running a container. The CLI parses the mac= attribute and stores it in NetworkConfiguration.swift:
container run -d \
--name api \
--network frontend,mac=02:42:ac:11:00:02 \
nginx:latest
The network helper reserves this MAC address on the bridge to prevent collisions.
Cleaning Up Networks
The runtime provides commands to remove unused networks while protecting active ones.
Pruning Unused Networks
Remove all networks that have zero attached containers:
container network prune
This preserves the default system network even if no containers are currently using it.
Deleting Specific Networks
To delete a specific network by name:
container network delete frontend
The XPC helper refuses to delete networks that still have attached containers, preventing accidental termination of active connectivity.
Key Implementation Files
The following source files define the container network lifecycle according to the apple/container source code:
Sources/Plugins/NetworkVmnet/NetworkVmnetHelper.swift– XPC service entry point that registers the default network plugin and handles vmnet interactions.Sources/ContainerResource/Network/NetworkConfiguration.swift– Data model for network specifications including plugin name, subnet, MAC address, and MTU settings.Sources/ContainerCommands/Network/NetworkCreate.swift– CLI implementation forcontainer network createand flag parsing.docs/command-reference.md– User-facing documentation for all network-related CLI commands.docs/technical-overview.md– High-level architectural description of the vmnet helper integration.
Summary
- Apple's container runtime uses the
container-network-vmnetXPC helper to manage networks via the macOS vmnet framework. - Networks require macOS 26+ for full functionality; macOS 15 only supports a single default network.
- Use
container network createto define custom subnets, which the helper stores as vmnet bridges. - Attach containers using
--network <name>with optional MAC address specifications. - Clean up unused networks with
container network pruneor delete specific ones withcontainer network delete. - The implementation spans
NetworkVmnetHelper.swift,NetworkConfiguration.swift, andNetworkCreate.swiftin the source tree.
Frequently Asked Questions
How does Apple's container runtime provide network isolation?
Network isolation is achieved by running each container in a lightweight Linux VM that connects to a vmnet bridge. The container-network-vmnet XPC helper creates separate NAT bridges for each user-defined network, ensuring traffic separation at the virtual hardware level. This architecture prevents containers on different networks from communicating directly while allowing outbound internet access through the host's connection.
Why are network commands unavailable on macOS 15?
The container network commands require APIs from the redesigned vmnet framework introduced in macOS 26. On macOS 15, the legacy vmnet implementation only supports a single default network bridge, making it impossible to create multiple isolated networks or configure custom subnets. Users on macOS 15 can only run containers using the default network with automatic IP allocation.
Can I use a custom network plugin instead of vmnet?
Yes, the architecture supports custom plugins through the NetworkPlugin protocol. When creating a network, specify an alternative plugin name using --plugin <my-plugin>. The plugin must implement the required protocol and reside under Sources/Plugins/. However, the default container-network-vmnet plugin is recommended as it provides native integration with macOS networking and requires no additional configuration.
What happens if I try to delete a network with running containers?
The XPC helper enforces referential integrity by refusing to delete networks that have attached containers. If you attempt to run container network delete on a network in use, the command will fail with an error indicating that containers are still attached. You must first stop or remove those containers, or use container network prune which only removes networks with zero attached containers.
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 →