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
| Driver | Isolation | DNS by Name | Multi-Host | Use Case |
|---|---|---|---|---|
bridge (default) | High | No | No | Single-host apps |
bridge (user-defined) | High | Yes | No | Single-host apps |
host | None | N/A | No | Performance, monitoring |
none | Complete | No | No | Secure batch jobs |
macvlan | High | No | No | Direct LAN access |
overlay | High | Yes | Yes | Multi-host Swarm |
When to Use Each
| Driver | When |
|---|---|
bridge (user-defined) | Default for all single-host apps |
host | Performance-critical, monitoring tools |
none | No network needed, maximum isolation |
macvlan | Container must appear as physical device on LAN |
overlay | Multi-host communication (Swarm) |
Bridge vs Host vs Macvlan
| Aspect | Bridge | Host | Macvlan |
|---|---|---|---|
| IP address | Container’s own (NAT) | Host’s IP | Container’s own (LAN) |
| Port mapping | Required (-p) | Not possible | Not needed |
| Performance | Good (NAT overhead) | Best (no NAT) | Excellent (no NAT) |
| LAN visibility | No (behind NAT) | Yes (host’s IP) | Yes (own MAC/IP) |
| Host-container comm | Yes | Yes | Limited (kernel) |
Macvlan Options
| Option | Purpose |
|---|---|
--subnet | Physical network subnet |
--gateway | Physical network gateway |
-o parent=eth0 | Host interface |
--ip-range | Container IP range |
--aux-address | Excluded 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
| Pitfall | Why It Happens | Fix |
|---|---|---|
| No DNS resolution | Default bridge | Use user-defined bridge |
| Port conflict | Host network | Change the port or use bridge |
| Container cannot reach host | Macvlan kernel restriction | Create host macvlan interface |
| No network at all | None driver | Use bridge or host |
| Performance lower than expected | Bridge NAT overhead | Use host or macvlan |
| Container not on LAN | Bridge NAT | Use macvlan |
| Cannot bind port | Host network conflict | Use 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
| Item | Value |
|---|---|
| Default driver | bridge |
| Bridge network | Isolated, NAT, port mapping |
| User-defined bridge | DNS resolution, isolation |
| Host network | Shares host, no isolation, best performance |
| None network | No networking, complete isolation |
| Macvlan network | Own MAC/IP, appears on LAN |
| Bridge DNS | No on default, yes on user-defined |
| Host limitation | Port conflicts, Linux only |
| Macvlan limitation | Host cannot reach containers |
| Macvlan parent | -o parent=eth0 |
Key takeaways:
- The
bridgedriver 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
hostdriver 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
nonedriver 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
macvlandriver 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
macvlandriver 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
bridgetrades performance for isolation. Thehosttrades isolation for performance. Thenonetrades connectivity for security. Themacvlantrades 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!