How to Create and Manage Custom Container Networks on macOS 26
Custom container networks on macOS 26 are fully isolated virtual LANs powered by the container-network-vmnet plugin, created via the container network CLI or the NetworkClient Swift API, and managed through XPC communication with the Container API Server.
The apple/container repository implements a native container networking stack for macOS 26 that abstracts the underlying vmnet framework into manageable virtual interfaces. When you create and manage custom container networks on macOS 26, you define isolated subnets that prevent traffic leakage between unrelated workloads, going beyond the built-in default network that starts automatically with the system.
Understanding the Network Architecture
The container networking subsystem follows a layered design that separates user-facing tools from kernel-level vmnet interfaces.
The vmnet Plugin and Default Network
At the core resides the container-network-vmnet plugin, which translates high-level network requests into native vmnet interfaces. When you run container system start, the platform initializes a built-in network called default (see Sources/Services/ContainerAPIService/Client/NetworkClient.swift lines 43-45). This network provides immediate connectivity for containers, but lacks the isolation required for multi-tenant or security-sensitive deployments.
Custom networks operate as completely isolated virtual LANs. Each custom network receives its own vmnet interface and cannot observe traffic from other networks, including the default network, as documented in docs/how-to.md.
XPC Communication Flow
Every network operation traverses a secure XPC pipeline:
- CLI parses arguments and builds an XPC message to the
com.apple.container.apiserverMach service - Container API Server receives the request and routes it to the network plugin
- Network Plugin (
container-network-vmnet) creates the vmnet interface, assigns IPv4/IPv6 CIDR blocks, and registers the state
The client-side implementation lives in NetworkClient.swift (lines 24-33), which handles the encoding of NetworkConfiguration objects and decoding of NetworkResource responses.
Creating Custom Container Networks
You can provision isolated networks through the command line or programmatically via Swift.
CLI Method with Custom Subnets
Use container network create to define a network with specific CIDR blocks. The following example creates a network named foo with explicit IPv4 and IPv6 ranges:
# Create a network with custom subnets
container network create foo \
--subnet 192.168.100.0/24 \
--subnet-v6 fd00:1234::/64
This command constructs an XPC networkCreate request (route: .networkCreate) and passes the encoded NetworkConfiguration to the server, ultimately invoking the NetworkClient.create method (see NetworkClient.swift lines 67-84).
Swift API Implementation
For programmatic control, import the ContainerResource and ContainerPlugin modules and instantiate NetworkClient:
import ContainerResource
import ContainerPlugin
let client = NetworkClient()
// Define a custom network configuration
let config = NetworkConfiguration(
id: "my-custom-net",
name: "my-custom-net",
subnet: "192.168.200.0/24",
subnetv6: "fd00:abcd::/64",
internal: false,
labels: [:],
options: [:],
plugin: "container-network-vmnet"
)
// Create the network
let network = try await client.create(configuration: config)
print("Created network \(network.id) with IPv4 \(network.subnet)")
Listing and Inspecting Networks
To view all provisioned networks, including their state and subnet assignments:
container network list
This executes the NetworkClient.list method (lines 91-104 in NetworkClient.swift), which sends a networkList XPC request and decodes the returned [NetworkResource]. The output resembles:
NETWORK STATE SUBNET
default running 192.168.64.0/24
foo running 192.168.100.0/24
Attaching Containers to Custom Networks
Launch containers on your isolated network using the --network flag:
container run -d --name web --network foo --rm web-test
Containers attached to foo can communicate with each other within the 192.168.100.0/24 range, but remain isolated from containers on the default network or other custom networks.
Deleting and Pruning Networks
Networks persist until explicitly removed or pruned, provided no containers remain attached.
Delete a Specific Network
Remove a network by name:
container stop web
container network delete foo
This triggers NetworkClient.delete (lines 21-33 in NetworkClient.swift), which sends a networkDelete request. The server verifies zero container attachments before destroying the vmnet interface.
Prune Unused Networks
Clean up all unused networks while preserving the built-in default network:
container network prune
This command removes any network with zero container attachments, as documented in docs/command-reference.md.
Summary
- Custom networks on macOS 26 are isolated virtual LANs backed by the
container-network-vmnetplugin, distinct from the built-in default network. - Creation occurs via
container network createor theNetworkClient.createAPI, supporting custom IPv4/IPv6 CIDR blocks. - Communication flows through XPC to the
com.apple.container.apiserverMach service, implemented inSources/Services/ContainerAPIService/Client/NetworkClient.swift. - Lifecycle management includes listing (
network list), deleting (network delete), and pruning (network prune) operations that check for active container attachments. - Isolation guarantees that traffic on one custom network cannot reach containers on another network or the default network.
Frequently Asked Questions
How does the default network differ from custom container networks on macOS 26?
The default network initializes automatically when you run container system start and provides general connectivity without custom CIDR configuration. Custom networks are explicitly created via container network create or the NetworkClient API, offering complete isolation from other networks and support for user-defined IPv4/IPv6 subnets. According to the apple/container source code, custom networks receive dedicated vmnet interfaces that filter traffic at the virtualization layer.
Can I create internal networks that block external traffic?
Yes. When creating a network via the Swift API, set the internal parameter to true in the NetworkConfiguration initializer. This restricts the network to container-to-container communication only, preventing external routing. The CLI equivalent uses the --internal flag during container network create.
What happens if I try to delete a network with running containers?
The deletion operation fails. The NetworkClient.delete method (implemented in NetworkClient.swift) sends a networkDelete request that triggers a server-side validation check. The server ensures no containers remain attached to the network before removing the vmnet interface. You must stop and remove all attached containers before the network can be deleted, or use container network prune to remove only unused networks.
Where are network configurations stored in the apple/container repository?
Network configuration logic resides in Sources/Services/ContainerAPIService/Client/NetworkClient.swift, which defines the XPC client methods for create, list, and delete operations. User-facing documentation appears in docs/how-to.md (covering isolation and creation workflows) and docs/command-reference.md (detailing CLI options). The plugin loader that registers container-network-vmnet is implemented in Sources/ContainerPlugin/PluginLoader.swift.
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 →