Networking in Docker
Learn how to configure communication between containers and external networks
Docker networking enables containers to communicate with each other and with the outside world. Understanding Docker's networking capabilities is essential for building multi-container applications. In this section, we'll explore Docker's network types, how to configure them, and best practices for container communication.
Docker Network Basics
Docker provides several network drivers, each with different capabilities:
- bridge: The default network driver. Containers can communicate with each other on the same bridge network.
- host: Removes network isolation between the container and the host. The container uses the host's networking directly.
- none: Disables all networking for a container.
- overlay: Connects multiple Docker daemons across hosts, enabling Swarm services to communicate.
- macvlan: Assigns a MAC address to a container, making it appear as a physical device on your network.
- ipvlan: Similar to macvlan but uses IP addresses instead of MAC addresses.
- custom network plugins: Allows you to use third-party network plugins.
Listing Docker Networks
To see all networks on your system:
docker network ls
Example output:
NETWORK ID NAME DRIVER SCOPE
7ddf8d0d099a bridge bridge local
69f9f6aa8de7 host host local
aabb90487e7c none null local
The Default Bridge Network
When you install Docker, it creates a default bridge network named bridge
. Unless you specify otherwise, new containers connect to this network.
To inspect the bridge network:
docker network inspect bridge
This returns a JSON object with details about the network, including subnet information and connected containers.
Creating a Custom Bridge Network
The default bridge network is fine for simple setups, but custom bridge networks offer several advantages:
- Automatic DNS resolution between containers
- Better isolation
- Containers can be connected and disconnected from networks on the fly
To create a custom bridge network:
docker network create my-network
You can specify additional options:
docker network create --driver bridge \
--subnet 172.18.0.0/16 \
--gateway 172.18.0.1 \
my-custom-network
Connecting Containers to Networks
At Container Creation
To start a container connected to a specific network:
docker run -d --name web --network my-network nginx:latest
Adding Running Containers to Networks
To connect an existing container to a network:
docker network connect my-network db
Removing a Container from a Network
To disconnect a container from a network:
docker network disconnect my-network db
Container Name Resolution
One of the most powerful features of custom bridge networks is automatic DNS resolution. Containers on the same custom network can reach each other using their container names.
Let's demonstrate with a simple example:
# Create a network
docker network create app-network
# Start a container
docker run -d --name db --network app-network postgres:13
# Start another container and connect to the first one using its name
docker run -d --name web --network app-network -p 8080:80 nginx:latest
Now, inside the web
container, you can connect to the db
container using the hostname db
:
docker exec -it web bash
ping db
The ping should succeed, showing that the containers can resolve each other by name.
Using the Host Network
Sometimes, you want a container to share the host's network stack, completely removing network isolation:
docker run -d --name host-nginx --network host nginx:latest
In this case, the container uses the host's IP address and ports directly. If nginx listens on port 80 inside the container, it will be available on the host's port 80. This means you don't need to use port mapping.
The host network is useful for:
- Maximum performance (no network overhead)
- When a container needs to handle a large range of ports
- When the container needs access to local network services
Note: The host network driver only works on Linux hosts.
Using the None Network
For maximum isolation, you can disable networking for a container:
docker run -d --name isolated --network none alpine sleep infinity
This container has only a loopback interface and cannot communicate with the outside world or other containers.
Port Mapping
For containers on bridge networks, port mapping is needed to make services accessible from outside Docker:
docker run -d --name web -p 8080:80 nginx:latest
This maps port 80 in the container to port 8080 on the host.
You can also specify the host IP to bind to:
docker run -d --name web -p 127.0.0.1:8080:80 nginx:latest
This only exposes the port on localhost, not on all host interfaces.
For a random host port, use:
docker run -d --name web -p 127.0.0.1::80 nginx:latest
Docker assigns a random available port. To see which port was assigned:
docker port web
Network Inspection and Troubleshooting
To see which containers are connected to a network:
docker network inspect my-network
For containers with connectivity issues, you can look at their network settings:
docker inspect --format='{{json .NetworkSettings}}' web | jq
This uses jq
to format the JSON output (install it if you don't have it).
Container-to-Container Communication Example
Let's build a practical example with a web application that connects to a database:
# Create a network
docker network create webapp-network
# Start a MongoDB container
docker run -d \
--name mongo \
--network webapp-network \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=password \
mongo:latest
# Start a Node.js application that connects to MongoDB
docker run -d \
--name nodeapp \
--network webapp-network \
-p 3000:3000 \
-e MONGO_URL=mongodb://admin:password@mongo:27017/myapp \
myapp:latest
In this example:
- Both containers join the
webapp-network
- The Node.js application uses
mongo
as the hostname to connect to MongoDB - Only the Node.js application exposes a port to the host
Docker Networking with Compose
Docker Compose simplifies networking for multi-container applications. We'll cover this in depth in the next section, but here's a preview of how networking works in Compose:
version: '3'
services:
web:
image: nginx:latest
ports:
- '8080:80'
db:
image: postgres:13
environment:
POSTGRES_PASSWORD: example
When you run docker-compose up
, Compose automatically:
- Creates a default network for the composition
- Connects all services to this network
- Sets up name resolution between services
Overlay Networks for Multi-Host Communication
If you're running Docker in Swarm mode (a cluster of Docker hosts), overlay networks allow containers on different hosts to communicate as if they were on the same host:
# Initialize a swarm
docker swarm init
# Create an overlay network
docker network create --driver overlay my-overlay-network
# Create a service using this network
docker service create \
--name my-service \
--network my-overlay-network \
--replicas 2 \
nginx:latest
Exposing Container Services to the Outside World
For production applications, you often need to expose services to external clients. Here are common patterns:
Direct Port Mapping
The simplest approach is port mapping, as we've seen:
docker run -d -p 80:80 -p 443:443 --name web nginx:latest
Using a Reverse Proxy
For more sophisticated setups, a reverse proxy like Nginx or Traefik can route traffic to different containers:
# Create a network
docker network create proxy-network
# Run backend services
docker run -d --name api1 --network proxy-network myapi:latest
docker run -d --name api2 --network proxy-network myotherapi:latest
# Run the reverse proxy
docker run -d \
--name nginx-proxy \
--network proxy-network \
-p 80:80 \
-v $(pwd)/nginx.conf:/etc/nginx/conf.d/default.conf \
nginx:latest
With a configuration like:
server {
listen 80;
location /api1 {
proxy_pass http://api1:8000;
}
location /api2 {
proxy_pass http://api2:8000;
}
}
Network Security Considerations
When designing Docker networks, consider these security best practices:
Use custom bridge networks for better isolation between container groups.
Limit exposed ports to only what's necessary.
Use host-private interfaces when possible:
docker run -d -p 127.0.0.1:8080:80 --name web nginx:latest
Remove the default bridge network from containers that don't need external access.
Implement network policies if using Kubernetes or Docker Enterprise.
Network Performance Considerations
For applications where network performance is critical:
Use the host network when maximum performance is required:
docker run -d --network host --name fast-app my-performance-app
Consider non-bridge drivers like macvlan for near-native performance.
Enable IPv6 if your environment supports it:
docker network create --ipv6 --subnet fd00::/80 ipv6-network
Tune MTU settings for your containers if working in environments with non-standard MTU:
docker network create --opt com.docker.network.driver.mtu=1400 lowmtu-network
Running Containers in the Cloud
When deploying containerized applications to the cloud, networking is a crucial consideration. DigitalOcean provides robust networking features for container-based applications, including private networks between Droplets.
Sign up with DigitalOcean to get $200 in free credits and deploy your networked container applications in a production-ready environment.
Network Troubleshooting Tools
When debugging network issues, these commands are helpful:
# Check network connectivity from inside a container
docker exec -it container-name ping other-container
# Examine container network interfaces
docker exec -it container-name ip addr show
# Trace network path
docker exec -it container-name traceroute other-container
# Analyze network traffic
docker exec -it container-name tcpdump -i eth0
For containers without these tools installed, you can use a network troubleshooting container:
docker run --rm -it --network container:target-container nicolaka/netshoot
This gives you a container with networking tools that shares the target container's network namespace.
Clean Up Networks
To remove an unused network:
docker network rm my-network
To remove all unused networks:
docker network prune
In the next section, we'll explore Docker Compose, which simplifies the management of multi-container applications including their networking configuration.
Found an issue?