| |

Docker 31 🐳 Container Networking Architecture: Bridge, Host, None, and Macvlan Drivers

A container’s network is not one thing. It is a namespace, a set of interfaces, a routing table, and a driver that constructs all three. The driver determines whether the container is isolated, shares the host’s network, or appears as a physical device on the LAN. The choice of driver is the choice of how the container participates in the network, and the wrong choice produces either a security gap or a connectivity failure that is difficult to diagnose.

This chapter covers the four fundamental Docker network drivers: bridge, host, none, and macvlan. You will learn what each driver does, how the container’s network namespace is constructed, when each one is the right choice, and the limitations that make the wrong choice painful.

Key point: The bridge driver creates an isolated network on the host, with the container behind NAT. The host driver removes the isolation entirely, sharing the host’s network namespace. The none driver removes networking altogether. The macvlan driver gives the container its own MAC address and IP on the physical LAN, making it appear as a separate device. The choice depends on whether the container needs isolation, performance, or direct LAN presence.


Why network drivers matter

The isolation problem. A container should not be able to reach everything on the host by default. The bridge driver provides isolation: the container is on its own subnet, behind NAT, and can only reach the outside world through the host’s routing and firewall rules. The host driver removes that isolation, and the none driver provides complete isolation.

The performance problem. The bridge driver adds a layer of NAT between the container and the network. Every packet is translated, and the translation has a cost. The host driver removes the NAT, and the container’s traffic goes directly through the host’s interfaces. The performance difference is measurable, and for latency-sensitive applications it matters .

The LAN presence problem. Some applications expect to be on the physical network, not behind a NAT. A legacy application that relies on broadcast discovery, a monitoring tool that needs to see all traffic, an IoT device that must have a specific IP on the LAN—these require the container to appear as a physical device. The macvlan driver provides this by assigning the container its own MAC address and IP on the physical subnet .

The security problem. The none driver is the most secure: the container has no network access at all. The bridge driver is the next: the container is isolated and can only reach what the NAT rules allow. The host driver is the least isolated: the container shares the host’s network and can bind any port, which is a security consideration .

The simplicity problem. The bridge driver is the default, and it is the right choice for most applications. The other drivers are for the cases where the default’s isolation or NAT is a problem. Knowing when the default is wrong is knowing when to reach for the others.


a. The bridge driver: isolation with NAT

The bridge driver is the default. When a container starts without a --network flag, it connects to the default bridge network, which is backed by a Linux bridge called docker0 .

docker run -d --name web nginx
docker network inspect bridge

The container gets an IP from the 172.17.0.0/16 range, and the host’s docker0 interface is the gateway. The container can reach the outside world through NAT, and the outside world can reach the container only through published ports .

The default bridge has a limitation: containers cannot resolve each other by name. They can only communicate by IP address . The fix is a user-defined bridge network, which provides automatic DNS resolution between containers on the same network .

docker network create my-net
docker run -d --name web --network my-net nginx
docker run -it --rm --network my-net alpine ping web

The user-defined bridge is the recommended form. It provides isolation, DNS resolution, and the ability to connect and disconnect containers on the fly . The default bridge is not recommended for production .

The bridge driver is the right choice for most single-host applications. It provides isolation, NAT for outbound traffic, and published ports for inbound traffic. The performance overhead is the NAT, which is usually acceptable.


b. The host driver: no isolation, maximum performance

The host driver removes the network isolation between the container and the host. The container shares the host’s network namespace, which means it has the host’s IP address and can bind to the host’s ports directly .

docker run -d --name web --network host nginx

The container binds to port 80 on the host’s IP. There is no port mapping, and the -p flag is ignored or produces an error. The container’s network performance is the host’s network performance, with no NAT overhead .

The host driver is appropriate when the performance matters, when the container needs to bind to many ports dynamically, or when the container needs to discover other services via multicast or broadcast . Network monitoring tools and peer-discovery services are the common cases .

The limitation is the port conflict. If the host already uses port 80, the container cannot bind to it. The container and the host share the same port space, and the conflict is not resolved automatically . The host driver also works only on Linux; it is not supported on Docker Desktop for Mac or Windows .


c. The none driver: complete isolation

The none driver disables networking entirely. The container gets only the loopback interface, and it cannot send or receive network traffic .

docker run -d --name isolated --network none alpine sleep 1d
docker exec isolated ip addr
# Only lo is present

The none driver is for the containers that do not need networking: batch jobs that process mounted volumes, security-sensitive workloads that should never have network access, and tests that need a completely isolated environment .

The none driver is not available for Swarm services . It is a Docker Engine feature for standalone containers.


d. The macvlan driver: direct LAN presence

The macvlan driver assigns each container its own MAC address and IP address on the physical network. The container appears as a separate physical device on the LAN, and the Docker daemon routes traffic to it by its MAC address .

docker network create -d macvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  -o parent=eth0 \
  pub_net

The --subnet and --gateway are the physical network’s subnet and gateway. The -o parent=eth0 specifies the host interface that the macvlan network attaches to. The container gets an IP from the subnet and is reachable from other machines on the LAN as if it were a physical device .

The macvlan driver is the right choice when the container must appear on the physical network: legacy applications that expect to be directly connected, monitoring tools that need to see all traffic, and services that require their own LAN IP .

The limitation is that the host cannot communicate with the macvlan containers through the same physical interface. This is a kernel restriction, and the workaround is to create a macvlan interface on the host itself . The macvlan driver also requires the network equipment to handle promiscuous mode, and an excessive number of MAC addresses can degrade the network .


Complete Example Session

# ============================================
# PART 1: DEFAULT BRIDGE
# ============================================
docker run -d --name web nginx
docker network inspect bridge
# ============================================
# PART 2: USER-DEFINED BRIDGE
# ============================================
docker network create my-net
docker run -d --name web1 --network my-net nginx
docker run -it --rm --network my-net alpine ping web1
# ============================================
# PART 3: HOST NETWORK
# ============================================
docker run -d --name web --network host nginx
curl http://localhost:80
# ============================================
# PART 4: NONE NETWORK
# ============================================
docker run -d --name isolated --network none alpine sleep 1d
docker exec isolated ip addr
# ============================================
# PART 5: MACVLAN NETWORK
# ============================================
docker network create -d macvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  -o parent=eth0 \
  pub_net
# ============================================
# PART 6: MACVLAN CONTAINER
# ============================================
docker run -d --name web --network pub_net --ip=192.168.1.50 nginx
curl http://192.168.1.50
# ============================================
# PART 7: PORT PUBLISHING ON BRIDGE
# ============================================
docker run -d --name web -p 8080:80 nginx
curl http://localhost:8080
# ============================================
# PART 8: DNS RESOLUTION
# ============================================
docker run -it --rm --network my-net alpine ping web1
# ============================================
# PART 9: CONNECT A CONTAINER TO A NETWORK
# ============================================
docker network connect my-net web
# ============================================
# PART 10: LIST NETWORKS
# ============================================
docker network ls

The ten parts covered the default bridge, the user-defined bridge, the host network, the none network, the macvlan network, the macvlan container, port publishing, DNS resolution, connecting a container to a network, and listing the networks.


Quick Reference

Network Driver Comparison

DriverIsolationDNS by NameMulti-HostUse Case
bridge (default)HighNoNoSingle-host apps
bridge (user-defined)HighYesNoSingle-host apps
hostNoneN/ANoPerformance, monitoring
noneCompleteNoNoSecure batch jobs
macvlanHighNoNoDirect LAN access
overlayHighYesYesMulti-host Swarm

When to Use Each

DriverWhen
bridge (user-defined)Default for all single-host apps
hostPerformance-critical, monitoring tools
noneNo network needed, maximum isolation
macvlanContainer must appear as physical device on LAN
overlayMulti-host communication (Swarm)

Bridge vs Host vs Macvlan

AspectBridgeHostMacvlan
IP addressContainer’s own (NAT)Host’s IPContainer’s own (LAN)
Port mappingRequired (-p)Not possibleNot needed
PerformanceGood (NAT overhead)Best (no NAT)Excellent (no NAT)
LAN visibilityNo (behind NAT)Yes (host’s IP)Yes (own MAC/IP)
Host-container commYesYesLimited (kernel)

Macvlan Options

OptionPurpose
--subnetPhysical network subnet
--gatewayPhysical network gateway
-o parent=eth0Host interface
--ip-rangeContainer IP range
--aux-addressExcluded IPs

Best Practices

✅ Do This:

# Use user-defined bridge for most applications
docker network create my-net                                    # ✅

# Use host for performance-critical applications
docker run --network host nginx                                 # ✅

# Use none for isolated batch jobs
docker run --network none alpine                                # ✅

# Use macvlan for direct LAN presence
docker network create -d macvlan --subnet=... -o parent=eth0    # ✅

# Publish ports on bridge networks
docker run -p 8080:80 nginx                                     # ✅

# Use DNS names on user-defined bridge networks
docker run --network my-net alpine ping web1                    # ✅

# Verify the network configuration
docker network inspect my-net                                   # ✅

❌ Don’t Do This:

# Don't use the default bridge for production
docker run nginx  # default bridge, no DNS                            # ⚠️

# Don't use host network without checking port conflicts
docker run --network host nginx  # port 80 conflict                   # ⚠️

# Don't use none for applications that need networking
docker run --network none nginx  # nginx cannot work                  # ❌

# Don't expect host-container communication on macvlan
# Kernel restriction, use a workaround                                 # ⚠️

# Don't use macvlan without checking the physical network
# The parent interface must be on the correct subnet                   # ⚠️

# Don't use the default bridge for multi-container apps
# No DNS resolution, only IP addresses                                 # ❌

# Don't forget that host mode is Linux-only
# Not supported on Docker Desktop for Mac or Windows                   # ❌

Common Pitfalls

PitfallWhy It HappensFix
No DNS resolutionDefault bridgeUse user-defined bridge
Port conflictHost networkChange the port or use bridge
Container cannot reach hostMacvlan kernel restrictionCreate host macvlan interface
No network at allNone driverUse bridge or host
Performance lower than expectedBridge NAT overheadUse host or macvlan
Container not on LANBridge NATUse macvlan
Cannot bind portHost network conflictUse bridge with -p

Real-World Examples

1. Default Bridge

docker run -d --name web nginx

2. User-Defined Bridge

docker network create my-net
docker run -d --name web --network my-net nginx

3. Host Network

docker run -d --name web --network host nginx

4. None Network

docker run -d --name isolated --network none alpine sleep 1d

5. Macvlan Network

docker network create -d macvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  -o parent=eth0 pub_net

6. Macvlan Container

docker run -d --name web --network pub_net --ip=192.168.1.50 nginx

7. Publish Ports

docker run -d -p 8080:80 nginx

8. Connect to Network

docker network connect my-net web

9. Inspect Network

docker network inspect my-net

10. List Networks

docker network ls

Visual

Bridge Network

┌─────────────────────────────────────────────────────────────┐
│  HOST                                                       │
│  ┌─────────────────────────────────────────────────────┐    │
│  │  docker0 (172.17.0.1)                               │    │
│  │  ┌─────────────────────────────────────────────┐    │    │
│  │  │  Container A (172.17.0.2)                   │    │    │
│  │  │  Container B (172.17.0.3)                   │    │    │
│  │  └─────────────────────────────────────────────┘    │    │
│  │                                                     │    │
│  │  NAT to eth0 (192.168.1.10)                         │    │
│  └─────────────────────────────────────────────────────┘    │
│                                                             │
│  Containers behind NAT. Isolated from LAN.                   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Host Network

┌─────────────────────────────────────────────────────────────┐
│  HOST (192.168.1.10)                                        │
│  ┌─────────────────────────────────────────────────────┐    │
│  │  Container shares the host's network stack          │    │
│  │  Container binds to host's ports directly           │    │
│  └─────────────────────────────────────────────────────┘    │
│                                                             │
│  No isolation. No NAT. Maximum performance.                 │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Macvlan Network

┌─────────────────────────────────────────────────────────────┐
│  PHYSICAL LAN (192.168.1.0/24)                              │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐          │
│  │  Host       │  │ Container A │  │ Container B │          │
│  │ 192.168.1.10│  │ 192.168.1.50│  │ 192.168.1.51│          │
│  │ MAC: aa:bb  │  │ MAC: cc:dd  │  │ MAC: ee:ff  │          │
│  └─────────────┘  └─────────────┘  └─────────────┘          │
│                                                             │
│  Containers appear as physical devices on the LAN.          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Driver Decision

┌─────────────────────────────────────────────────────────────┐
│  Does the container need network access?                    │
│    │                                                        │
│    ├── NO ──▶ none                                          │
│    │                                                        │
│    └── YES                                                  │
│          │                                                  │
│          ▼                                                  │
│  Does it need to appear on the physical LAN?                │
│    │                                                        │
│    ├── YES ──▶ macvlan                                      │
│    │                                                        │
│    └── NO                                                   │
│          │                                                  │
│          ▼                                                  │
│  Does performance matter more than isolation?               │
│    │                                                        │
│    ├── YES ──▶ host                                         │
│    │                                                        │
│    └── NO ──▶ bridge (user-defined)                         │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Summary

ItemValue
Default driverbridge
Bridge networkIsolated, NAT, port mapping
User-defined bridgeDNS resolution, isolation
Host networkShares host, no isolation, best performance
None networkNo networking, complete isolation
Macvlan networkOwn MAC/IP, appears on LAN
Bridge DNSNo on default, yes on user-defined
Host limitationPort conflicts, Linux only
Macvlan limitationHost cannot reach containers
Macvlan parent-o parent=eth0

Key takeaways:

  • The bridge driver is the default and the right choice for most applications. It provides isolation, NAT for outbound traffic, and port mapping for inbound traffic. The user-defined bridge is preferred over the default because it provides DNS resolution between containers .
  • The host driver removes network isolation. The container shares the host’s network namespace, which means it has the host’s IP and can bind to the host’s ports. The performance is the best because there is no NAT, but the port conflicts are possible .
  • The none driver disables networking entirely. The container has only the loopback interface. It is for the containers that do not need network access and for the workloads that require complete isolation .
  • The macvlan driver gives the container its own MAC and IP on the physical LAN. The container appears as a separate device on the network. It is for the legacy applications that expect to be directly connected, the monitoring tools, and the services that require their own LAN IP .
  • The macvlan driver has a kernel restriction. The host cannot communicate with the macvlan containers through the same physical interface. The workaround is to create a macvlan interface on the host .
  • The user-defined bridge is the recommended default. It provides the isolation of the bridge with the DNS resolution that the default bridge lacks. The containers can resolve each other by name, and the network can be configured per project .
  • The choice of driver is the choice of the trade-off. The bridge trades performance for isolation. The host trades isolation for performance. The none trades connectivity for security. The macvlan trades the NAT for direct LAN presence. The right choice depends on which trade-off the application needs.

Remember: The network driver is not a detail. It determines how the container participates in the network, and the wrong choice produces either a security gap or a connectivity failure. The bridge is the default because it is the right choice for most applications. The host is for the cases where the NAT overhead matters. The none is for the cases where the network access is not needed. The macvlan is for the cases where the container must appear on the physical LAN. And the user-defined bridge is the preferred form of the bridge because it provides the DNS resolution and the isolation that the default lacks.



Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!