Skip to main content

Docker Network

Introduction

When working with Docker containers, understanding how they communicate with each other and with the outside world is essential. Docker networking provides the infrastructure that enables containers to connect and exchange data with other containers, the host system, and external networks.

In this guide, we'll explore Docker's networking capabilities, different network types, and how to configure them for your containerized applications.

Docker Networking Fundamentals

At its core, Docker creates a virtual network environment where containers can communicate securely. When you install Docker, it automatically creates three networks:

  • bridge: The default network for containers
  • host: A network that removes network isolation between container and host
  • none: A network with no connectivity

Let's examine how Docker networking works:

Each container gets its own virtual Ethernet interface (eth0) that connects to the Docker bridge. The bridge then provides connectivity to other containers and the outside world.

Network Types in Docker

Docker provides several network drivers to accommodate different use cases:

1. Bridge Networks

The default network type in Docker. Containers on the same bridge network can communicate with each other.

Let's create a custom bridge network:

bash
docker network create my-bridge-network

To see the network you created:

bash
docker network ls

Output:

NETWORK ID     NAME                DRIVER    SCOPE
1a2b3c4d5e6f bridge bridge local
7g8h9i0j1k2l host host local
3m4n5o6p7q8r none null local
9s0t1u2v3w4x my-bridge-network bridge local

Now, let's run containers on this network:

bash
docker run -d --name container1 --network my-bridge-network nginx
docker run -d --name container2 --network my-bridge-network nginx

Containers on the same bridge network can communicate using their container names as hostnames:

bash
docker exec container1 ping -c 2 container2

Output:

PING container2 (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: icmp_seq=0 ttl=64 time=0.086 ms
64 bytes from 172.18.0.3: icmp_seq=1 ttl=64 time=0.134 ms

2. Host Network

Containers using the host network mode share the network namespace with the host. This means they use the host's IP address and port space.

bash
docker run -d --name host-container --network host nginx

In this case, if nginx is using port 80, it will be directly accessible at http://localhost:80 without any port mapping.

3. Overlay Networks

Overlay networks enable communication between containers running on different Docker hosts, making them ideal for Docker Swarm services.

First, initialize a swarm:

bash
docker swarm init

Create an overlay network:

bash
docker network create --driver overlay my-overlay-network

Deploy a service using this network:

bash
docker service create --name my-service --network my-overlay-network nginx

4. Macvlan Networks

Macvlan allows you to assign a MAC address to a container, making it appear as a physical device on your network.

bash
docker network create -d macvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
-o parent=eth0 my-macvlan-network

Run a container on this network:

bash
docker run -d --name macvlan-container --network my-macvlan-network nginx

5. None Network

For complete network isolation, you can use the none network driver:

bash
docker run -d --name isolated-container --network none nginx

This container will have no network connectivity whatsoever.

Network Configuration

Port Mapping

To allow external access to services running in containers, you'll need to map container ports to host ports:

bash
docker run -d --name web-server -p 8080:80 nginx

This maps the container's port 80 to port 8080 on the host, making the nginx server accessible at http://localhost:8080.

Connecting Containers to Multiple Networks

Containers can connect to multiple networks:

bash
docker network connect my-second-network container1

Now container1 is connected to both my-bridge-network and my-second-network.

Custom IP Addresses

You can assign specific IP addresses to containers within a user-defined network:

bash
docker run -d --name custom-ip-container --network my-bridge-network --ip 172.18.0.10 nginx

Inspecting Networks

To view detailed information about a network:

bash
docker network inspect my-bridge-network

Output:

json
[
{
"Name": "my-bridge-network",
"Id": "9s0t1u2v3w4x...",
"Created": "2023-04-20T12:34:56.789012345Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"Containers": {
"abc123...": {
"Name": "container1",
"EndpointID": "def456...",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
},
"ghi789...": {
"Name": "container2",
"EndpointID": "jkl012...",
"MacAddress": "02:42:ac:12:00:03",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]

Real-World Example: Web Application Stack

Let's build a simple web application stack with a frontend, backend API, and database, all connected via Docker networks:

bash
# Create a network for the application
docker network create app-network

# Run a MongoDB container
docker run -d --name mongodb \
--network app-network \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=password \
mongo:latest

# Run a Node.js backend API
docker run -d --name api \
--network app-network \
-e MONGODB_URI=mongodb://admin:password@mongodb:27017 \
-p 3000:3000 \
my-node-api:latest

# Run a React frontend
docker run -d --name frontend \
--network app-network \
-e API_URL=http://api:3000 \
-p 80:80 \
my-react-app:latest

In this setup:

  • All containers are on the same app-network
  • The MongoDB container is only accessible to other containers on the network
  • The API container can reach MongoDB using its container name as the hostname
  • The frontend container can reach the API using its container name
  • Only the API and frontend ports are published to the host

Networking with Docker Compose

Docker Compose makes it easy to define and manage multi-container applications, including their networks:

yaml
version: '3'

networks:
frontend-network:
backend-network:

services:
nginx:
image: nginx:latest
networks:
- frontend-network
ports:
- "80:80"

app:
image: my-app:latest
networks:
- frontend-network
- backend-network

database:
image: postgres:latest
networks:
- backend-network
environment:
POSTGRES_PASSWORD: secret

In this example:

  • nginx and app can communicate over the frontend-network
  • app and database can communicate over the backend-network
  • nginx and database cannot directly communicate (security by isolation)

To start this stack:

bash
docker-compose up -d

Common Networking Issues and Troubleshooting

1. DNS Resolution Problems

If containers can't resolve each other's names:

bash
# Check DNS configuration
docker exec container1 cat /etc/resolv.conf

# Try using explicit IP instead of hostname
docker exec container1 ping 172.18.0.3

2. Port Conflicts

If you encounter port binding errors:

bash
# Find which process is using the port
sudo lsof -i :8080

# Use a different port
docker run -d -p 8081:80 nginx

3. Network Connectivity Issues

Test connectivity between containers:

bash
# Install network utilities if needed
docker exec container1 apt-get update && apt-get install -y iputils-ping net-tools

# Try pinging
docker exec container1 ping container2

# Check network configuration
docker exec container1 ifconfig

Summary

Docker networking is a powerful feature that allows containers to communicate with each other and with external networks. We've covered:

  • Basic networking concepts in Docker
  • Different network drivers (bridge, host, overlay, macvlan, none)
  • Network configuration and port mapping
  • Multi-network setups for containers
  • Real-world examples with Docker and Docker Compose
  • Troubleshooting common networking issues

Understanding Docker networking is essential for building robust containerized applications, especially when dealing with microservices architectures.

Additional Resources

Exercises

  1. Create a custom bridge network and run two containers that can communicate with each other.
  2. Set up a three-tier application (web, app, database) using Docker networks to isolate the database from direct external access.
  3. Experiment with the host network mode and observe the differences in network behavior.
  4. Use Docker Compose to create a network configuration that isolates frontend and backend services.
  5. Configure a container with a static IP address on a custom network.


If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)