# How to Manage Multiple Networks in Container on macOS Using NetworkCommand

> Master multiple networks in macOS containers with NetworkCommand. Create, inspect, and attach your containers to isolated virtual networks using the vmnet framework.

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

---

**The `NetworkCommand` suite in Apple's Container project enables you to create, inspect, and attach macOS containers to multiple isolated virtual networks using the vmnet framework, with each network definition persisted as a `NetworkResource` in the system configuration.**

The Apple Container project implements its networking stack on macOS through the **`container-network-vmnet`** plugin. Understanding how to manage multiple networks in container on macOS using NetworkCommand allows you to segment traffic between frontend and backend services, configure custom subnets, and maintain persistent network topologies that survive daemon restarts. The CLI forwards all network operations to the Container API Service (`/container/v1/network`), which translates requests into calls to the underlying vmnet framework via the Networks harness and service layers.

## Understanding the NetworkCommand Architecture

The `NetworkCommand` struct in [`Sources/ContainerCommands/Network/NetworkCommand.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Network/NetworkCommand.swift) serves as the root command that registers five sub-commands: **`NetworkCreate`**, **`NetworkDelete`**, **`NetworkList`**, **`NetworkInspect`**, and **`NetworkPrune`**. Each command builds an appropriate request payload and communicates with the daemon through the **`ContainerAPIClient`** over gRPC.

When you invoke `container network create`, the CLI constructs a **`NetworkConfiguration`** object ([`Sources/ContainerResource/Network/NetworkConfiguration.swift`](https://github.com/apple/container/blob/main/Sources/ContainerResource/Network/NetworkConfiguration.swift)) containing your specified subnet, gateway, MTU, and labels. The daemon persists this as a **`NetworkResource`** ([`Sources/ContainerResource/Network/NetworkResource.swift`](https://github.com/apple/container/blob/main/Sources/ContainerResource/Network/NetworkResource.swift)) via [`ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/ContainerSystemConfig.swift), ensuring your network definitions survive daemon restarts. The actual virtual switch creation happens in the **`container-network-vmnet`** plugin ([`Sources/Plugins/NetworkVmnet/NetworkVmnetHelper.swift`](https://github.com/apple/container/blob/main/Sources/Plugins/NetworkVmnet/NetworkVmnetHelper.swift)), which exposes Mach services such as `com.apple.container.network.hydra`.

## Creating Isolated Network Segments

Create independent networks with distinct subnets to isolate container traffic. The CLI validates name uniqueness, IPAM settings, and driver options before forwarding to the plugin.

Define a frontend network with specific addressing:

```bash
container network create \
    --label purpose=frontend \
    --subnet 10.1.0.0/24 \
    --gateway 10.1.0.1 \
    --mtu 1500 \
    frontend

```

Define a backend network with custom MAC prefixing:

```bash
container network create \
    --label purpose=backend \
    --subnet 10.2.0.0/24 \
    --gateway 10.2.0.1 \
    --mac-prefix 02:42:ac \
    backend

```

*Implementation detail*: The `NetworkCreate` struct in [`Sources/ContainerCommands/Network/NetworkCreate.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Network/NetworkCreate.swift) converts these flags into a `NetworkConfiguration` instance, which the daemon stores via `ContainerSystemConfig`.

## Listing and Inspecting Networks

View all defined networks sorted by name:

```bash
container network ls

```

*Behind the scenes*: The `NetworkList` command ([`Sources/ContainerCommands/Network/NetworkList.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Network/NetworkList.swift)) queries the `NetworksHarness` for the current snapshot of `NetworkResource` objects.

Retrieve detailed JSON output for a specific network:

```bash
container network inspect frontend

```

The output includes fields such as `ID`, `Name`, `Subnet`, `Gateway`, `MTU`, and labels. This maps to the `NetworkInspectOutput` structure used in integration tests (`Tests/IntegrationTests/Utilities/ContainerFixture+NetworkHelpers.swift`).

## Attaching Containers to Multiple Networks

Attach a single container to multiple networks simultaneously using comma-separated values:

```bash
container run -d \
    --name web \
    --network frontend,backend \
    nginx:stable

```

*What happens internally*: The CLI expands the comma-separated list and builds a `ContainerResource.Attachment` array (see `ContainerFixture+ContainerHelpers.swift` in integration tests). The daemon creates a **`NetworkStatus`** entry for each attachment, exposing the assigned MAC address, IP address, and hostname to the container runtime. The container receives two network interfaces—for example, `10.1.0.5` on *frontend* and `10.2.0.5` on *backend*.

Verify the dual attachment from within the container:

```bash
container exec web ip addr show

```

You will see two `ethX` interfaces, each displaying the IP and MAC allocated by their respective `NetworkStatus` entries.

## Removing and Pruning Networks

The `NetworkDelete` command ([`Sources/ContainerCommands/Network/NetworkDelete.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Network/NetworkDelete.swift)) prevents removal of networks currently referenced by running containers.

Attempting to delete an attached network fails:

```bash
container network delete frontend

# Error: network is in use

```

First stop and remove the container, then delete the network:

```bash
container stop web && container rm web
container network delete frontend

```

Remove all unused networks with a single command:

```bash
container network prune

```

The `NetworkPrune` implementation ([`Sources/ContainerCommands/Network/NetworkPrune.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Network/NetworkPrune.swift)) queries the `ContainerSystemConfig` for networks with no active attachments and removes them from the persistent store.

## Summary

- **`NetworkCommand`** serves as the root CLI entry point for all network operations, delegating to `NetworkCreate`, `NetworkDelete`, `NetworkList`, `NetworkInspect`, and `NetworkPrune`.
- Networks are defined as **`NetworkResource`** objects stored in **`ContainerSystemConfig`**, ensuring persistence across daemon restarts.
- The **`container-network-vmnet`** plugin implements the actual virtual networking using the vmnet framework and Mach services.
- Containers can attach to multiple networks simultaneously, receiving separate IP addresses and MAC addresses for each network interface.
- The CLI enforces safety checks by preventing deletion of networks with active container attachments.

## Frequently Asked Questions

### Can a macOS container attach to multiple networks at the same time?

Yes. The `container run` command accepts comma-separated network names via the `--network` flag. The CLI constructs a `ContainerResource.Attachment` array for each network, and the daemon creates corresponding `NetworkStatus` entries that provide separate IP addresses and MAC addresses for each network interface inside the container.

### Where does the Container daemon store network configurations?

Network definitions persist in **`ContainerSystemConfig`** ([`Sources/ContainerPersistence/ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/ContainerSystemConfig.swift)). This storage mechanism maintains the list of `NetworkResource` objects and their state across daemon restarts, ensuring that your isolated network segments remain available after system reboots.

### Which component implements the actual virtual networking on macOS?

The **`container-network-vmnet`** plugin ([`Sources/Plugins/NetworkVmnet/NetworkVmnetHelper.swift`](https://github.com/apple/container/blob/main/Sources/Plugins/NetworkVmnet/NetworkVmnetHelper.swift)) implements the networking layer by interfacing with Apple's vmnet framework. It creates virtual switches (VMnet) and exposes Mach services such as `com.apple.container.network.hydra` to handle packet forwarding between containers and the host.

### Why does `container network delete` report an error for some networks?

The deletion command checks for active references in the `ContainerSystemConfig`. If any container maintains a `NetworkStatus` entry for the target network, the `NetworkDelete` command aborts with an error to prevent accidental disruption of running workloads. You must stop and remove all attached containers before the network can be safely deleted.