# How to Configure Custom Networks for Containers in Apple Container

> Learn to configure custom networks for containers in Apple Container. Set default subnets, create specific networks with subnets, and attach containers easily.

- Repository: [Apple/container](https://github.com/apple/container)
- Tags: how-to-guide
- Published: 2026-06-25

---

**To configure custom networks for containers, edit `~/.config/container/config.toml` to set default subnets, use `container network create` with `--subnet` flags for specific networks, and attach containers with `container run --network <name>`.**

The `apple/container` project implements container networking on top of the **vmnet** framework, exposing both a command-line interface and a Swift-level API for managing isolated network segments. Network configuration persists in a TOML-based system config file and supports custom IPv4/IPv6 CIDR blocks, MAC address assignment, and MTU customization.

## Understanding Container Network Architecture

The networking subsystem relies on several core concepts defined in the source code.

### Default and Reserved Networks

The system maintains two special network identifiers hardcoded in [`Sources/Services/ContainerAPIService/Client/NetworkClient.swift`](https://github.com/apple/container/blob/main/Sources/Services/ContainerAPIService/Client/NetworkClient.swift):

- **`default`** – The automatic network created on first use (`NetworkClient.defaultNetworkName = "default"`). This network cannot be deleted.
- **`none`** – A reserved identifier (`NetworkClient.noNetworkName = "none"`) that instructs the runtime to run a container without any network attachment.

### Configuration File Structure

The `NetworkConfig` struct in [`Sources/ContainerPersistence/ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/ContainerSystemConfig.swift) maps the TOML schema to runtime objects. The `[network]` section accepts optional `subnet` and `subnetv6` entries that supply defaults for newly created networks.

## Setting Global Network Defaults

You can establish system-wide defaults by modifying `~/.config/container/config.toml`. These values apply only when creating networks without explicit subnet flags.

```toml
[network]
subnet = "192.168.100.1/24"      # IPv4 CIDR

subnetv6 = "fd00:abcd::/64"     # IPv6 CIDR

```

The [`ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/ContainerSystemConfig.swift) file parses these values at startup, injecting them into the `NetworkConfig` struct used by the XPC service.

## Creating and Managing Custom Networks

### CLI Network Creation

Use the `container network create` command to establish isolated vmnet networks. The CLI supports custom subnets and internal-only isolation.

```bash

# Basic network named "foo"

container network create foo

# With custom IPv4 and IPv6 subnets

container network create foo \
    --subnet 192.168.100.0/24 \
    --subnet-v6 fd00:1234::/64

```

The command serializes the configuration and sends it to the daemon, which returns a `NetworkResource` representing the created segment.

### Swift API Network Creation

For programmatic control, instantiate `NetworkClient` and invoke `create(configuration:)`. This method encodes the configuration as JSON and transmits it via XPC to the server.

```swift
import ContainerPlugin
import ContainerResource
import ContainerXPC

let client = NetworkClient()
let config = NetworkConfiguration(
    id: "foo",
    subnet: CIDRv4("192.168.100.0/24"),
    subnetv6: CIDRv6("fd00:1234::/64")
)
Task {
    do {
        let resource = try await client.create(configuration: config)
        print("Created network: \(resource.id)")
    } catch {
        print("Failed: \(error)")
    }
}

```

The implementation in [`Sources/Services/ContainerAPIService/Client/NetworkClient.swift`](https://github.com/apple/container/blob/main/Sources/Services/ContainerAPIService/Client/NetworkClient.swift) (lines 67-88) handles the encoding and XPC routing through the `networkCreate` route.

## Attaching Containers to Networks

Attach containers to your custom network using the `--network` flag with `container run` or `container create`. You can optionally specify a MAC address or MTU inline.

```bash
container run -d --name my-web \
    --network foo,mac=02:42:ac:11:00:02 \
    nginx:latest

```

The container receives an IP address from the chosen network's subnet. Use `container ls` to verify the assigned address. As documented in [`docs/command-reference.md`](https://github.com/apple/container/blob/main/docs/command-reference.md), the `--network` flag accepts comma-separated options for fine-grained control.

## Cleaning Up Networks

Remove unused networks with the delete command. Networks can only be deleted when no containers remain attached.

```bash
container network delete foo

```

Note that the built-in `default` network is protected and will reject deletion attempts, as enforced by the `defaultNetworkName` constant in [`NetworkClient.swift`](https://github.com/apple/container/blob/main/NetworkClient.swift).

## Summary

- **Global defaults** are configured in `~/.config/container/config.toml` under the `[network]` section, parsed by [`ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/ContainerSystemConfig.swift).
- **Custom networks** are created via `container network create` with `--subnet` and `--subnet-v6` flags, or programmatically via `NetworkClient.create(configuration:)`.
- **Container attachment** uses `container run --network <name>` with optional MAC/MTU parameters.
- **Reserved networks** include `default` (required, auto-created) and `none` (isolated mode).
- **Implementation** relies on the vmnet framework with XPC communication defined in [`Sources/Services/ContainerAPIService/Client/NetworkClient.swift`](https://github.com/apple/container/blob/main/Sources/Services/ContainerAPIService/Client/NetworkClient.swift).

## Frequently Asked Questions

### How do I run a container without any network access?

Use the reserved `none` network name. According to `NetworkClient.noNetworkName` in [`NetworkClient.swift`](https://github.com/apple/container/blob/main/NetworkClient.swift), passing `--network none` to `container run` instructs the runtime to skip network interface creation entirely, resulting in an isolated container with no network connectivity.

### Can I modify the subnet of the default network after creation?

No. The default network (`NetworkClient.defaultNetworkName = "default"`) is created automatically on first use and its configuration is fixed. To use custom subnets, create a new user-defined network with `container network create` and specify your desired CIDR blocks with `--subnet` flags.

### What happens if I don't specify subnets when creating a network?

The system falls back to values defined in `~/.config/container/config.toml`. If the `[network]` section is absent or incomplete, the vmnet framework assigns default values automatically. The `NetworkConfig` struct in [`ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/ContainerSystemConfig.swift) handles this resolution logic.

### Is the Swift API available to third-party applications?

Yes. The `NetworkClient` class in [`Sources/Services/ContainerAPIService/Client/NetworkClient.swift`](https://github.com/apple/container/blob/main/Sources/Services/ContainerAPIService/Client/NetworkClient.swift) is part of the public framework. It exposes asynchronous methods like `create(configuration:)` that encode `NetworkConfiguration` objects as JSON and communicate with the XPC service, allowing external Swift applications to manage container networks programmatically.