LFCE 133 ๐ง Docker Networking โ Bridge, Host, Overlay
The three network drivers that cover most Docker deployments are bridge, host, and overlay. Bridge is the default and the most common: it gives each container its own network namespace and connects it to a virtual switch on the host. Host removes that namespace entirely, putting the container directly on the host’s network stack. Overlay connects containers across multiple Docker hosts, using VXLAN to tunnel traffic between them. Each driver answers a different question about isolation and reachability.
This chapter covers the configuration and behavior of these three drivers in practice: creating user-defined bridges with custom subnets and DNS, using host networking for performance and port access, and setting up an overlay network for multi-host communication. It also covers the port publishing rules that apply to bridge and overlay networks, and the --attachable flag that allows standalone containers to join an overlay.
Key point: The default bridge network does not resolve container names. A user-defined bridge does. This is the single most important difference for multi-container applications on the same host.
Why these three drivers cover most use cases
The single-host problem. Containers on the same Docker host need to communicate. The bridge driver provides this by creating a virtual network that only the containers on that host can see. A user-defined bridge adds DNS, so a container named db is reachable as http://db:5432 without hardcoding an IP that changes on restart .
The performance problem. The bridge driver adds NAT and a virtual interface between the container and the host’s physical network. For applications that need maximum throughput or that need to bind to a port the host is already using, the host driver removes that overhead entirely. The container shares the host’s network namespace, so it binds directly to the host’s interfaces .
The multi-host problem. A bridge network is scoped to one Docker daemon. If a service’s containers run on three different hosts, they cannot communicate over a bridge. The overlay driver creates a virtual network that spans the hosts, using VXLAN to encapsulate traffic. This is the foundation of Docker Swarm services, but it can also be used with standalone containers if the network is created with --attachable .
a. Bridge: the default and user-defined networks
When Docker is installed, it creates a default bridge network called bridge. Every container without a --network flag attaches to it. The default bridge has two significant limitations: containers cannot resolve each other by name, and every container that does not specify a network shares the same bridge, which means unrelated containers can communicate .
A user-defined bridge is created with docker network create. It provides automatic DNS resolution: Docker runs an embedded DNS server at 127.0.0.11 inside each container’s namespace, and it resolves container names and network aliases on the same network . It also scopes the network: only containers explicitly attached to it can communicate.
# Create a user-defined bridge with a custom subnet
docker network create --subnet 172.20.0.0/16 my-net
# Run a container on it
docker run -d --network my-net --name db postgres
# Another container on the same network resolves "db" by name
docker run --rm --network my-net curlimages/curl curl http://db:5432
Containers on the same user-defined bridge can reach each other on any port. For a port to be accessible from outside the network, it must be published with -p or --publish. The default binding is all host addresses, but it can be restricted to a specific interface, such as 127.0.0.1, which is the recommended practice when a reverse proxy is the public-facing endpoint .
b. Host: removing the network namespace
The host driver makes the container share the host’s network namespace. The container does not get its own IP address, and port mapping does not apply. If the container binds to port 80, the application is available on port 80 of the host’s IP address .
# Run nginx on the host's port 80 directly
docker run --rm -d --network host nginx
The performance benefit is real: there is no NAT, no bridge, and no userland proxy. The trade-off is the complete loss of network isolation. The container can bind any port on the host, and two containers cannot bind the same port. The Docker documentation recommends host networking for performance optimization and for containers that need to handle a large range of ports .
Host networking is supported on Docker Engine for Linux. On Docker Desktop, it requires enabling the feature in Settings and is supported from version 4.34. It is not supported for Windows containers.
c. Overlay: multi-host networking
The overlay driver connects multiple Docker daemons. It requires Swarm mode to be initialized, even for standalone containers, because the overlay network depends on the Swarm control plane to distribute network state .
# Initialize Swarm (required for overlay)
docker swarm init
# Create an overlay network
docker network create --driver overlay my-overlay
# Create an attachable overlay for standalone containers
docker network create --driver overlay --attachable my-attachable-overlay
By default, overlay networks are only available to Swarm services. The --attachable flag allows standalone containers to join the network . Containers on the same overlay can resolve each other by name, regardless of which host they run on.
Overlay traffic is encapsulated in VXLAN and sent over UDP port 4789. The control plane uses TCP and UDP port 7946. If the hosts are separated by a firewall, these ports must be open . Encryption is optional and is enabled with --opt encrypted, which applies IPsec to the VXLAN traffic. The documentation warns that this imposes a performance penalty and should be tested before production use .
Complete Example Session
# ============================================
# PART 1: THE DEFAULT BRIDGE (NAME RESOLUTION FAILS)
# ============================================
docker run -d --name web nginx
docker run -d --name db postgres -e POSTGRES_PASSWORD=pass
docker exec web curl http://db:5432
# curl: (6) Could not resolve host: db
# ============================================
# PART 2: CREATE A USER-DEFINED BRIDGE
# ============================================
docker network create --subnet 172.20.0.0/16 app-net
docker run -d --network app-net --name db2 postgres -e POSTGRES_PASSWORD=pass
docker run -d --network app-net --name web2 nginx
# ============================================
# PART 3: DNS RESOLUTION ON THE USER-DEFINED BRIDGE
# ============================================
docker exec web2 curl http://db2:5432
# Connection succeeds (or returns a protocol error, not a DNS error)
# ============================================
# PART 4: PUBLISH A PORT
# ============================================
docker run -d --network app-net -p 8080:80 --name web-pub nginx
curl http://localhost:8080
# ============================================
# PART 5: RESTRICT THE BINDING ADDRESS
# ============================================
docker run -d --network app-net -p 127.0.0.1:8081:80 --name web-local nginx
# Accessible only from the host itself
# ============================================
# PART 6: HOST NETWORKING
# ============================================
docker run --rm -d --network host --name web-host nginx
curl http://localhost:80
# No -p flag needed; port 80 is bound directly
# ============================================
# PART 7: HOST NETWORKING IGNORES -p
# ============================================
docker run --rm --network host -p 8080:80 nginx
# WARNING: Published ports are discarded when using host network mode
# ============================================
# PART 8: INITIALIZE SWARM FOR OVERLAY
# ============================================
docker swarm init --advertise-addr <manager-ip>
# ============================================
# PART 9: CREATE AN OVERLAY NETWORK
# ============================================
docker network create --driver overlay --attachable my-overlay
docker run -d --network my-overlay --name web-ov nginx
docker run -d --network my-overlay --name db-ov postgres -e POSTGRES_PASSWORD=pass
# ============================================
# PART 10: VERIFY AND CLEAN UP
# ============================================
docker network ls
docker network inspect app-net
docker network rm app-net
# Error if containers are connected; disconnect first
The ten parts covered the default bridge’s DNS failure, user-defined bridge creation, DNS resolution, port publishing, binding restriction, host networking, the ignored -p flag, Swarm initialization, overlay creation, and cleanup.
Quick Reference
Driver comparison
| Driver | Isolation | Multi-host | DNS by name | Port mapping |
|---|---|---|---|---|
bridge (default) | Yes | No | No | Yes |
bridge (user-defined) | Yes, scoped | No | Yes | Yes |
host | None | No | N/A | Ignored |
overlay | Yes, scoped | Yes | Yes | Yes (overlay) |
Bridge commands
| Command | Purpose |
|---|---|
docker network create <name> | Create user-defined bridge |
docker network create --subnet <cidr> <name> | Custom subnet |
docker network connect <net> <ctr> | Attach running container |
docker network disconnect <net> <ctr> | Detach |
docker network rm <name> | Remove (no connected containers) |
Host networking
| Flag | Effect |
|---|---|
--network host | Share host’s network namespace |
-p | Ignored (warning) |
| Platform | Linux; Docker Desktop 4.34+ with feature enabled |
Overlay requirements
| Requirement | Detail |
|---|---|
| Swarm mode | docker swarm init |
| Attachable | --attachable for standalone containers |
| Ports | TCP/UDP 7946, UDP 4789 |
| Encryption | --opt encrypted (IPsec, performance penalty) |
Port publishing
| Syntax | Effect |
|---|---|
-p 8080:80 | Host port 8080 โ container 80 |
-p 127.0.0.1:8080:80 | Bind only to localhost |
-p 8080:80/udp | UDP port |
No -p | Container not reachable from outside |
Best Practices
โ Do This:
# Use a user-defined bridge for container communication
docker network create app-net # โ
# Publish ports only for services that need external access
docker run -p 8080:80 nginx # โ
# Restrict bindings to localhost when a proxy fronts the service
docker run -p 127.0.0.1:8080:80 nginx # โ
# Use --attachable for overlay networks with standalone containers
docker network create -d overlay --attachable my-overlay # โ
โ Don’t Do This:
# Rely on the default bridge for multi-container apps
docker run --name web nginx # no DNS # โ
# Use host networking in multi-tenant environments
docker run --network host nginx # โ
# Create an overlay without Swarm initialized
docker network create -d overlay my-overlay # โ
# Encrypt overlay traffic without testing the performance impact
docker network create -d overlay --opt encrypted my-overlay # โ (test first)
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| Container name does not resolve | On the default bridge | Use a user-defined bridge |
| Port not reachable from host | No -p flag | Publish the port |
Host networking ignores -p | Host mode shares the namespace | Remove -p; bind directly |
| Overlay network fails | Swarm not initialized | Run docker swarm init |
| Standalone container cannot join overlay | Network not --attachable | Recreate with --attachable |
| Overlay containers on different hosts cannot communicate | Firewall blocks VXLAN | Open TCP/UDP 7946 and UDP 4789 |
| Network removal fails | Active endpoints | Disconnect containers first |
Real-World Examples
1. Create a user-defined bridge
docker network create --subnet 172.20.0.0/16 app-net
2. Run containers on it
docker run -d --network app-net --name db postgres
docker run -d --network app-net --name web nginx
3. Resolve by name
docker exec web curl http://db:5432
4. Publish a port
docker run -d -p 8080:80 nginx
5. Restrict to localhost
docker run -d -p 127.0.0.1:8080:80 nginx
6. Host networking
docker run --rm -d --network host nginx
7. Initialize Swarm
docker swarm init --advertise-addr 10.0.0.1
8. Create an attachable overlay
docker network create -d overlay --attachable my-overlay
9. Run on the overlay
docker run -d --network my-overlay --name web nginx
10. Inspect a network
docker network inspect app-net
Visual
User-defined bridge DNS
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ USER-DEFINED BRIDGE โ
โ โ
โ Host โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ app-net (172.20.0.0/16) โโ
โ โ โ โโ
โ โ โโโ db (172.20.0.2) โโ
โ โ โ DNS: db โ 172.20.0.2 โโ
โ โ โ โโ
โ โ โโโ web (172.20.0.3) โโ
โ โ DNS: web โ 172.20.0.3 โโ
โ โ โโ
โ โ web resolves "db" via 127.0.0.11 โโ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Host networking
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ HOST DRIVER โ
โ โ
โ Host network namespace โ
โ โโโ eth0 (10.0.0.1) โ
โ โโโ lo โ
โ โโโ container (shares this namespace) โ
โ binds port 80 directly โ
โ โ
โ No NAT, no bridge, no separate IP. โ
โ The container is on the host's network. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Overlay across hosts
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ OVERLAY โ
โ โ
โ Host 1 Host 2 โ
โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ
โ โ web โ โ db โ โ
โ โ 10.0.0.2 โ โ 10.0.0.3 โ โ
โ โโโโโโโโฌโโโโโโโโ โโโโโโโโฌโโโโโโโโ โ
โ โ โ โ
โ โผ โผ โ
โ VXLAN (UDP 4789) VXLAN โ
โ โ โ โ
โ โโโโโโโโโโโ network โโโโโโโโโโโโโ โ
โ โ
โ web resolves "db" and connects across hosts. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Port publishing decision
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ PUBLISH OR NOT? โ
โ โ
โ Container-to-container on the same bridge? โ
โ โโโ No -p needed; all ports are reachable internally โ
โ โ
โ External access needed? โ
โ โโโ Public? โโโบ -p 8080:80 โ
โ โโโ Behind proxy? โโโบ -p 127.0.0.1:8080:80 โ
โ โ
โ Host networking? โ
โ โโโ -p is ignored; bind directly on the host โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary
| Item | Value |
|---|---|
| Default bridge | bridge, no DNS, shared by all containers |
| User-defined bridge | DNS by name, scoped, configurable |
| Host driver | Shares host network namespace, -p ignored |
| Overlay driver | Multi-host, VXLAN, requires Swarm |
| Overlay attachable | --attachable for standalone containers |
| Overlay ports | TCP/UDP 7946, UDP 4789 |
| Port publishing | -p host:container, optional bind address |
| DNS resolver | 127.0.0.11 inside container namespace |
Key takeaways:
- The default bridge is not for production. It lacks DNS resolution and is shared by every container that does not specify a network. A user-defined bridge provides both name resolution and scoped isolation .
- User-defined bridges run an embedded DNS server. Docker injects container names and network aliases into
127.0.0.11, which is whyhttp://db:5432works without hardcoding IPs. The default bridge has no such registration . - The host driver removes network isolation entirely. The container shares the host’s network namespace, binds directly to host ports, and ignores
-p. It is appropriate for performance-sensitive workloads and system-level tools, not for multi-tenant environments . - Overlay networks require Swarm mode. The driver uses the Swarm control plane to distribute network state. The
--attachableflag allows standalone containers to join, but Swarm must be initialized first . - Overlay traffic uses VXLAN on UDP 4789. Firewalls between hosts must allow this port, along with TCP/UDP 7946 for the control plane. Encryption is optional and imposes a performance penalty .
- Port publishing is only for external access. Containers on the same user-defined bridge can reach each other on any port without
-p. Publishing is for traffic from outside the Docker network, and binding to127.0.0.1is the safer default when a proxy fronts the service .
Remember: Docker networking is a decision about isolation and reachability. The bridge driver isolates containers on one host. The host driver removes isolation for performance. The overlay driver connects hosts. The default bridge is a starting point that lacks DNS and scoping; a user-defined bridge is the production choice for single-host communication. Publish ports only for services that need external access, and restrict bindings when a proxy is the public endpoint. For multi-host communication, initialize Swarm, create an attachable overlay, and open the VXLAN ports between hosts.
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!