Skip to main content

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:

bash
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:

bash
docker network inspect bridge

Output (abbreviated):

json
[
{
"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:

bash
# 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:

bash
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:

bash
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?

bash
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:

bash
docker network create --driver bridge my_custom_bridge

Now let's create containers that use this network:

bash
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:

bash
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:

bash
docker network inspect my_custom_bridge

Output (abbreviated):

json
[
{
"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:

bash
# 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:

  1. We create a dedicated bridge network called app_network
  2. We launch a PostgreSQL container on this network
  3. We launch our web application container on the same network
  4. The web app can reach the database using the hostname postgres_db
  5. 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:

bash
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:

bash
# 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:

bash
docker network disconnect frontend webserver

Bridge Network Limitations

While bridge networks are useful, they do have limitations:

  1. Single Host Only: Bridge networks only work for containers on the same host
  2. Performance: There's a slight overhead due to network address translation
  3. Security: All containers on a bridge network can communicate by default
  4. 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

  1. Use custom bridge networks instead of the default bridge
  2. Create multiple bridge networks to isolate container groups
  3. Name your containers meaningfully to take advantage of DNS resolution
  4. Use environment variables for service discovery in your applications
  5. 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! :)