Docker Bridge Networking
Introduction
When you start working with Docker containers, one of the first challenges you'll face is how to connect them—both to each other and to the outside world. This is where Docker networking comes in, and the bridge network is Docker's default networking solution.
A bridge network in Docker creates a private internal network on the host where containers can communicate with each other while remaining isolated from the host's network. Think of it as a virtual switch that connects containers running on the same Docker host.
In this guide, we'll explore how Docker bridge networks function, how to create and manage them, and when you should use them in your containerized applications.
Docker Default Bridge Network
When you install Docker, it automatically creates a default bridge network named bridge
. This is the network that containers connect to by default if you don't specify a network when starting them.
Let's examine this default network:
docker network ls
Output:
NETWORK ID NAME DRIVER SCOPE
1234abc5def bridge bridge local
9876zyx5wvu host host local
abcdef123456 none null local
Understanding the Default Bridge
The default bridge network has some specific characteristics:
- All containers on the default bridge can communicate with each other via IP addresses
- Containers are not discoverable by DNS name (only by IP address)
- Containers connect to the outside world via Network Address Translation (NAT)
- Port mappings are required to allow external traffic to reach containers
Here's a diagram showing how the default bridge works:
Inspecting the Default Bridge
To see more details about the default bridge network:
docker network inspect bridge
Output (abbreviated):
[
{
"Name": "bridge",
"Id": "1234abc5def...",
"Created": "2023-04-01T14:00:00.00000000Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Containers": {},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
}
}
]
Creating Containers on the Default Bridge
Let's create two containers and see how they interact on the default bridge network:
# Start two containers with default networking
docker run -d --name container1 nginx
docker run -d --name container2 nginx
Now, let's check their IP addresses:
docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container1
docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container2
Output:
/container1 - 172.17.0.2
/container2 - 172.17.0.3
Testing Container Connectivity
Let's test if container1 can ping container2:
docker exec container1 ping -c 2 172.17.0.3
Output:
PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: icmp_seq=0 ttl=64 time=0.103 ms
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.110 ms
--- 172.17.0.3 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.103/0.107/0.110/0.000 ms
But what if we try to ping by name?
docker exec container1 ping -c 2 container2
Output:
ping: container2: Name or service not known
This illustrates a key limitation of the default bridge network: containers cannot resolve each other by name.
User-Defined Bridge Networks
To overcome limitations of the default bridge, Docker allows you to create your own custom bridge networks, which provide:
- Automatic DNS resolution between containers
- Better isolation
- More control over container networking
- The ability to attach and detach containers from networks on the fly
Creating a Custom Bridge Network
Let's create a custom bridge network:
docker network create --driver bridge my_custom_bridge
Now let's create containers that use this network:
docker run -d --name web --network my_custom_bridge nginx
docker run -d --name db --network my_custom_bridge postgres:14
Testing DNS Resolution on Custom Bridge
Let's see if containers can now refer to each other by name:
docker exec web ping -c 2 db
Output:
PING db (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: icmp_seq=0 ttl=64 time=0.114 ms
64 bytes from 172.18.0.3: icmp_seq=1 ttl=64 time=0.123 ms
--- db ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.114/0.119/0.123/0.000 ms
Success! Containers on custom bridge networks can resolve each other by name.
Inspecting a Custom Bridge Network
Let's see more details about our custom network:
docker network inspect my_custom_bridge
Output (abbreviated):
[
{
"Name": "my_custom_bridge",
"Id": "abcdef123456...",
"Created": "2023-04-01T15:00:00.00000000Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Containers": {
"abc123def456": {
"Name": "web",
"EndpointID": "123456...",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
},
"def456abc789": {
"Name": "db",
"EndpointID": "789012...",
"MacAddress": "02:42:ac:12:00:03",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
Practical Example: Web Application with Database
Let's create a real-world example with a web application connecting to a database:
# Create a network for our application
docker network create --driver bridge app_network
# Start a PostgreSQL database
docker run -d \
--name postgres_db \
--network app_network \
-e POSTGRES_PASSWORD=mysecretpassword \
-e POSTGRES_DB=myapp \
postgres:14
# Start a web application that connects to the database
docker run -d \
--name web_app \
--network app_network \
-e DATABASE_URL=postgres://postgres:mysecretpassword@postgres_db:5432/myapp \
-p 8080:3000 \
my-web-app:latest
In this example:
- We create a dedicated bridge network called
app_network
- We launch a PostgreSQL container on this network
- We launch our web application container on the same network
- The web app can reach the database using the hostname
postgres_db
- We map port 8080 on the host to port 3000 in the container to allow external access
Here's a diagram of this setup:
Advanced Bridge Network Features
Configuring the Subnet and Gateway
When creating a bridge network, you can specify custom subnet and gateway:
docker network create \
--driver bridge \
--subnet 192.168.100.0/24 \
--gateway 192.168.100.1 \
custom_bridge
Connecting a Container to Multiple Networks
A container can be connected to multiple networks:
# Create two networks
docker network create frontend
docker network create backend
# Create a container and connect to frontend
docker run -d --name webserver --network frontend nginx
# Connect the same container to backend network
docker network connect backend webserver
Now the webserver
container can communicate with containers on both networks.
Disconnecting from a Network
You can also disconnect a container from a network:
docker network disconnect frontend webserver
Bridge Network Limitations
While bridge networks are useful, they do have limitations:
- Single Host Only: Bridge networks only work for containers on the same host
- Performance: There's a slight overhead due to network address translation
- Security: All containers on a bridge network can communicate by default
- Static Configuration: Changes often require container restarts
For multi-host networking, you'll need to explore Docker Swarm mode or overlay networks.
Best Practices for Bridge Networks
- Use custom bridge networks instead of the default bridge
- Create multiple bridge networks to isolate container groups
- Name your containers meaningfully to take advantage of DNS resolution
- Use environment variables for service discovery in your applications
- Enable container security with network policies and restrictions
Summary
Docker bridge networks provide a simple but powerful way to enable container communication. In this guide, we've learned:
- How the default bridge network works
- Why custom bridge networks are preferable for most applications
- How to create and configure bridge networks
- How to connect containers to bridge networks
- Real-world applications of bridge networking
- Advanced features and limitations of bridge networks
With this knowledge, you're well-equipped to design effective networking solutions for your containerized applications.
Additional Resources
- Try creating a three-tier application with web, API, and database containers on custom bridge networks
- Experiment with network isolation by creating multiple bridge networks
- Learn about Docker's other networking drivers: overlay, macvlan, and host
- Explore Docker Compose for defining multi-container applications with networking
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)