# How to Create an Isolated Container Network with Custom Subnets

> Create an isolated container network with custom subnets using container network create. Define private networks with specific CIDR ranges to prevent conflicts.

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

---

**Use the `container network create` command with the `--internal` and `--subnet` flags to define a private, isolated network with a specific CIDR range that prevents overlap with existing networks.**

The `apple/container` CLI provides a dedicated `network` sub-command for defining private container networks with precise IP addressing requirements. When you need to isolate containers from external networks while controlling their IP allocation, the tool constructs a `NetworkConfiguration` object and processes it through the `NetworkClient` to the Container API server, which validates the requested subnets and configures the underlying VM-net interface.

## Understanding the Network Architecture

Creating an isolated container network with custom subnets involves a coordinated flow between the CLI, API client, and server-side network service. The architecture ensures that your specified CIDR ranges are validated against existing networks before the system reserves the address space.

In [`Sources/ContainerCommands/Network/NetworkCreate.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Network/NetworkCreate.swift), the `Application.NetworkCreate` struct parses user-provided flags like `--subnet` and `--internal` to build a configuration object. This `NetworkConfiguration` model, defined in [`Sources/ContainerResource/Network/NetworkConfiguration.swift`](https://github.com/apple/container/blob/main/Sources/ContainerResource/Network/NetworkConfiguration.swift), holds the optional `CIDRv4` and `CIDRv6` values alongside the network mode selection.

The `NetworkClient` transmits this configuration via a `POST /networks` request to the Container API server. On the server side, [`Sources/Services/Network/Server/DefaultNetworkService.swift`](https://github.com/apple/container/blob/main/Sources/Services/Network/Server/DefaultNetworkService.swift) implements the `DefaultNetworkService` class, which validates that requested subnets do not overlap with existing networks using the `validateSubnet` method. For custom subnets, the service creates a `ReservedVmnetNetwork` instance that configures the exact IPv4 CIDR you specified through the macOS `vmnet` framework.

## Creating an Isolated Network with Custom Subnets

### Step 1: Define the Network Configuration via CLI

The CLI entry point in [`NetworkCreate.swift`](https://github.com/apple/container/blob/main/NetworkCreate.swift) processes your command-line arguments to construct the network definition. When you specify `--internal`, the system sets the `NetworkMode` to `hostOnly`, creating an isolated network that prevents containers from reaching external networks or the internet.

The `--subnet` flag accepts a CIDR notation (e.g., `10.42.0.0/16`) that the CLI parses into the `NetworkConfiguration` structure. If you require IPv6 addressing, use `--subnet-v6` with an appropriate prefix like `fd00:1234::/48`.

### Step 2: Server-Side Validation and Allocation

Once the `NetworkClient` submits the configuration, the `DefaultNetworkService` performs collision detection. It checks your requested IPv4 subnet against all existing networks to ensure no overlap exists. This validation occurs before any system resources are allocated.

If you omit the `--subnet` flag, the service automatically allocates a non-overlapping subnet from the available pool. However, specifying a custom subnet triggers the creation of a `ReservedVmnetNetwork` rather than an `AllocationOnlyVmnetNetwork`, ensuring the system reserves your exact CIDR requirements.

### Step 3: VM-Net Interface Initialization

In [`Sources/Services/NetworkVmnet/Server/ReservedVmnetNetwork.swift`](https://github.com/apple/container/blob/main/Sources/Services/NetworkVmnet/Server/ReservedVmnetNetwork.swift), the service calls `vmnet_network_configuration_set_ipv4_subnet` to configure the macOS VM-net framework with your specific subnet. This low-level configuration enforces the isolation boundaries while respecting your custom IP address range.

The server returns the newly created network's UUID, which the CLI prints to stdout for use in subsequent container attachment commands.

## Complete CLI Examples

Create a completely isolated network with custom IPv4 and IPv6 subnets:

```bash

# Create an isolated network with specific CIDR ranges

container network create \
    --internal \
    --subnet 10.42.0.0/16 \
    --subnet-v6 fd00:1234::/48 \
    isolated-net

```

The command outputs the network UUID:

```

4e2d5a1b-c0f9-4c1a-a3e7-7e9f8c1d2b57

```

Attach a container to your isolated network:

```bash
container run \
    --network isolated-net \
    -p 8080:80 \
    nginx:latest

```

## Configuration Flags Explained

- **`-internal`**: Forces `NetworkMode.hostOnly`, creating an isolated network where containers can only communicate with each other and the host, blocking external internet access.
- **`--subnet <CIDR>`**: Specifies the IPv4 address range (e.g., `192.168.100.0/24`). The service validates this against existing networks to prevent overlap.
- **`--subnet-v6 <CIDR>`**: Defines the IPv6 prefix for the network. Unlike IPv4, IPv6 subnets must be explicitly provided if required; the service rejects overlapping prefixes.
- **`<network-name>`**: The human-readable identifier used when attaching containers via the `--network` flag in run commands.

## Summary

- Use `container network create` with `--internal` to achieve true network isolation via `NetworkMode.hostOnly`.
- Specify custom subnets with `--subnet` and `--subnet-v6` to control IP allocation within your container network.
- The `DefaultNetworkService` validates all custom subnets against existing networks to prevent CIDR collisions before creating the VM-net interface.
- Source files [`NetworkCreate.swift`](https://github.com/apple/container/blob/main/NetworkCreate.swift), [`NetworkConfiguration.swift`](https://github.com/apple/container/blob/main/NetworkConfiguration.swift), and [`ReservedVmnetNetwork.swift`](https://github.com/apple/container/blob/main/ReservedVmnetNetwork.swift) handle the complete pipeline from CLI parsing to low-level network configuration.
- Isolated networks restrict containers to host-only communication while custom subnets determine the available IP address ranges for attached containers.

## Frequently Asked Questions

### How does the container tool prevent subnet overlap?

The `DefaultNetworkService` in [`Sources/Services/Network/Server/DefaultNetworkService.swift`](https://github.com/apple/container/blob/main/Sources/Services/Network/Server/DefaultNetworkService.swift) implements a `validateSubnet` method that checks your requested CIDR against all existing networks before allocation. If the requested range overlaps with an existing network, the API returns an error and the creation fails.

### Can I create an isolated network without specifying a subnet?

Yes. If you omit the `--subnet` flag, the system automatically allocates a non-overlapping subnet from the available pool and creates an `AllocationOnlyVmnetNetwork`. However, if you require specific IP ranges for firewall rules or service discovery, you should explicitly define the subnet using the `--subnet` flag.

### What is the difference between `--internal` and omitting the flag?

The `--internal` flag sets `NetworkMode.hostOnly` in the `NetworkConfiguration`, which disables NAT and prevents the containers from reaching external networks. Without this flag, the network operates in NAT mode, allowing containers to access the internet through the host while remaining isolated from other container networks.

### Does the custom subnet configuration support IPv6?

Yes. Use the `--subnet-v6` flag to specify an IPv6 prefix such as `fd00:1234::/48`. The validation logic in `DefaultNetworkService` checks IPv6 prefixes for collisions similarly to IPv4, though IPv6 allocation is not automatic—you must explicitly provide the CIDR if you require IPv6 addressing.