Docker networking is one of the most fundamental concepts to understand when deploying containerized applications. Whether you're running a simple web application or a complex microservices architecture, containers must communicate with each other and, in many cases, with external systems. Among the various networking options provided by Docker, the bridge network is the default and most widely used networking model for containers running on a single Docker host.
A Docker bridge network enables containers to communicate seamlessly while maintaining network isolation from other containers and the external network. It acts as a virtual switch, allowing containers attached to the same bridge network to exchange traffic securely and efficiently.
In this comprehensive guide, we will explore Docker bridge networking from the ground up, covering key concepts such as bridge interfaces, virtual Ethernet (veth) pairs, IP addressing, DNS-based service discovery, port publishing, Network Address Translation (NAT), iptables rules, user-defined bridge networks, container-to-container communication, and common troubleshooting techniques.
What Is a Docker Bridge Network?
A Docker bridge network is a virtual Layer 2 network created and managed by the Docker Engine on the host system. It functions similarly to a physical network switch, connecting multiple containers to the same virtual network segment and enabling them to communicate with each other.
When a container is attached to a bridge network, Docker automatically creates a virtual network interface inside the container's network namespace. This interface is connected to a corresponding virtual Ethernet (veth) device on the host machine. One end of the veth pair resides inside the container, while the other end is connected to the Docker bridge interface on the host.
By default, Docker creates a bridge network named bridge, represented by the Linux bridge interface docker0. Containers attached to this network receive private IP addresses from Docker's internal IP address pool and can communicate with other containers on the same bridge network.
Key Characteristics of Docker Bridge Networks
Provides network isolation between containers and external networks.
Enables communication between containers connected to the same bridge.
Supports automatic IP address allocation.
Offers built-in DNS resolution for user-defined bridge networks.
Allows selective exposure of container services through port publishing.
Uses Linux networking components such as bridges, veth pairs, iptables, and NAT.
Default Bridge Network Architecture
When Docker starts, it creates the following networking components:
Docker Bridge Interface (docker0) – A virtual bridge acting as a software switch.
Virtual Ethernet Pairs (veth) – Connect containers to the bridge.
Container Network Namespace – Provides isolated networking for each container.
iptables Rules – Control packet forwarding and network address translation.
NAT Gateway – Allows containers to access external networks.
The traffic flow typically follows this path:
Container A
│
▼
veth Pair
│
▼
docker0 Bridge
│
▼
veth Pair
│
▼
Container B
This architecture allows containers on the same bridge network to communicate directly without requiring external routing.
In the following sections, we will examine how Docker creates bridge interfaces, assigns IP addresses, manages DNS resolution, implements NAT and port forwarding, and how user-defined bridge networks improve container communication and security.
Default Bridge vs User-Defined Bridge Networks
Docker provides two types of bridge networks: the default bridge network and user-defined bridge networks. While both are based on the same underlying bridge technology, they differ significantly in functionality, flexibility, and security.
Default Bridge Network
When the Docker Engine starts, it automatically creates a bridge network called bridge, which is associated with the Linux bridge interface docker0.
You can view it using:
docker network ls
Example output:
NETWORK ID NAME DRIVER SCOPE
a1b2c3d4e5f6 bridge bridge local
Containers launched without specifying a network are automatically attached to this default bridge network:
docker run -d nginx
Characteristics of the Default Bridge
Automatically created by Docker.
Uses the
docker0bridge interface.Containers receive private IP addresses from Docker's default subnet.
Supports container-to-container communication using IP addresses.
Does not provide automatic DNS-based name resolution.
Less secure because all containers on the default bridge share the same network unless additional restrictions are applied.
Example:
docker inspect container1
Output:
IPAddress: 172.17.0.2
To communicate with another container:
ping 172.17.0.3
Since DNS resolution is not enabled by default, containers must communicate using IP addresses or manually configured links.
User-Defined Bridge Networks
A user-defined bridge network is created explicitly by the administrator.
Example:
docker network create app-network
Verify:
docker network ls
Output:
NETWORK ID NAME DRIVER SCOPE
123abc456def app-network bridge local
Attach containers to the network:
docker run -d --name web --network app-network nginx
docker run -d --name api --network app-network nginx
Characteristics of User-Defined Bridges
Created manually by administrators.
Provides automatic DNS-based service discovery.
Containers can communicate using container names.
Better isolation between applications.
Supports custom subnets and IP ranges.
Easier to manage multi-container environments.
Recommended for production workloads.
Example:
docker exec -it web ping api
Docker automatically resolves the hostname:
PING api (172.18.0.3)
No manual IP lookup is required.
Comparison: Default vs User-Defined Bridge
| Feature | Default Bridge | User-Defined Bridge |
|---|---|---|
| Created Automatically | Yes | No |
| Docker Bridge Interface | docker0 | Dedicated bridge |
| DNS Resolution | No | Yes |
| Container Name Discovery | No | Yes |
| Network Isolation | Limited | Strong |
| Custom Subnet Support | Limited | Yes |
| Production Ready | Not Recommended | Recommended |
| Multi-Container Applications | Difficult | Easy |
Why User-Defined Bridges Are Preferred
For modern containerized applications, user-defined bridge networks are the preferred choice because they provide:
Automatic service discovery through Docker DNS.
Better network segmentation and security.
Easier application deployment and maintenance.
Cleaner communication between microservices.
Greater flexibility for custom networking requirements.
In production environments, most Docker Compose deployments and containerized applications rely on user-defined bridge networks rather than the default bridge network, making them the recommended approach for secure and scalable container communication.
Complete Working Demonstration of Docker Bridge Networking
Let's build a hands-on lab to understand how Docker bridge networking works in practice. This demonstration covers container creation, network inspection, DNS resolution, container-to-container communication, internet access, and port publishing.
Step 1: Create a User-Defined Bridge Network
Create a dedicated bridge network:
docker network create demo-bridge
Verify the network:
docker network ls
Expected output:
NETWORK ID NAME DRIVER
xxxxxxx bridge bridge
xxxxxxx demo-bridge bridge
Inspect the network:
docker network inspect demo-bridge
Example output:
{
"Name": "demo-bridge",
"Driver": "bridge",
"IPAM": {
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
}
}
Docker automatically creates a Linux bridge interface for this network.
Step 2: Launch Two Containers
Start two Alpine Linux containers:
docker run -dit --name app1 --network demo-bridge alpine sh
docker run -dit --name app2 --network demo-bridge alpine sh
Verify:
docker ps
Output:
CONTAINER ID NAME
123abc app1
456def app2
Step 3: Verify IP Address Assignment
Check app1:
docker inspect app1
Relevant section:
"IPAddress": "172.18.0.2"
Check app2:
"IPAddress": "172.18.0.3"
Docker automatically assigns IP addresses from the bridge subnet.
Step 4: Test Container-to-Container Communication
Enter app1:
docker exec -it app1 sh
Install ping utility:
apk add iputils
Ping app2 by IP:
ping 172.18.0.3
Expected output:
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.15 ms
Communication succeeds because both containers are connected to the same bridge network.
Step 5: Test Docker DNS Resolution
One of the biggest advantages of user-defined bridge networks is built-in DNS.
From app1:
ping app2
Output:
PING app2 (172.18.0.3)
Docker's embedded DNS server automatically resolves the container name.
No manual IP management is required.
Step 6: Verify Internet Connectivity
Inside app1:
ping google.com
Output:
PING google.com (142.x.x.x)
Docker performs NAT through the host's network stack.
Traffic flow:
Container
│
▼
Bridge Network
│
▼
Host NAT
│
▼
Internet
The container can access external networks without exposing itself directly.
Step 7: Run a Web Server
Launch an NGINX container:
docker run -d \
--name web \
--network demo-bridge \
-p 8080:80 \
nginx
Verify:
docker ps
Output:
PORTS
0.0.0.0:8080->80/tcp
Docker creates a port-forwarding rule from:
Host Port 8080
│
▼
Container Port 80
Step 8: Access the Application
From the Docker host:
curl http://localhost:8080
Or open:
http://<HOST_IP>:8080
You should see the default NGINX welcome page.
Step 9: Verify Communication Between Containers and NGINX
Enter app1:
docker exec -it app1 sh
Install curl:
apk add curl
Access the web container using Docker DNS:
curl http://web
Output:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
</head>
</html>
Docker resolves:
web
│
▼
172.18.0.x
automatically through its internal DNS service.
Step 10: Inspect Linux Bridge Interface
On the Docker host:
ip addr show
Example:
br-6a2f9d4f2b31
Inspect the bridge:
brctl show
Output:
bridge name bridge id
br-6a2f9d4f2b31 8000.xxxxxxxxxxxx
Docker creates a dedicated Linux bridge for every user-defined bridge network.
Step 11: View veth Pairs
On the host:
ip link show
Example:
veth7f3a@if5
veth91bc@if7
Each container receives:
Container eth0
│
▼
veth pair
│
▼
Linux Bridge
This virtual Ethernet pair connects the container namespace to the bridge network.
Step 12: Observe NAT Rules
View Docker's iptables rules:
sudo iptables -t nat -L -n
Example:
Chain DOCKER
target prot opt source destination
DNAT tcp -- anywhere anywhere
tcp dpt:8080 to:172.18.0.4:80
Docker automatically creates NAT and port-forwarding rules for published ports.
Complete Network Flow
Internet
▲
│
NAT / iptables
▲
│
Docker Host
▲
│
Linux Bridge Network
(demo-bridge)
▲ ▲
│ │
veth veth
│ │
app1 app2
│
▼
nginx
(Port 80)
Cleanup
Remove the lab environment:
docker rm -f app1 app2 web
docker network rm demo-bridge
This demonstration shows the complete lifecycle of Docker bridge networking, including bridge creation, IP allocation, DNS-based service discovery, veth connectivity, internet access through NAT, port publishing, and container-to-container communication in a real-world environment.