Docker Networking: Bridge, Host, Overlay - Complete Guide
Docker networking enables communication between containers, with the host, and across multiple hosts. Understanding Docker's network drivers—bridge, host, overlay, and others—is essential for building scalable, secure containerized applications. This comprehensive guide covers all Docker networking modes with practical examples and production best practices.
Table of Contents
- Introduction to Docker Networking
- Prerequisites
- Docker Network Architecture
- Bridge Network
- Host Network
- Overlay Network
- Macvlan Network
- None Network
- Container Networking
- Network Commands
- DNS and Service Discovery
- Network Security
- Production Best Practices
- Troubleshooting
- Conclusion
Introduction to Docker Networking
Docker networking provides isolated network environments for containers, enabling secure communication patterns while maintaining flexibility. Each network driver offers different capabilities suited for specific use cases, from single-host development to multi-host production clusters.
Docker Network Drivers
- Bridge: Default network for single-host container communication
- Host: Removes network isolation, uses host's networking directly
- Overlay: Enables multi-host networking for Swarm and Kubernetes
- Macvlan: Assigns MAC addresses to containers for legacy app integration
- None: Disables networking completely
- Custom: Third-party network plugins (Weave, Calico, etc.)
Why Docker Networking Matters
- Isolation: Separate network namespaces for security
- Service Discovery: Automatic DNS resolution between containers
- Load Balancing: Built-in load balancing across replicas
- Scalability: Network across multiple hosts
- Security: Network-level access control
Prerequisites
Before diving into Docker networking, ensure you have:
- Docker Engine installed (version 19.03 or higher)
- Root or sudo access
- Basic understanding of networking concepts (IP, subnet, gateway)
- Multiple containers or services for testing
- For overlay networks: Docker Swarm initialized
Verify Docker installation:
docker --version
docker network ls
Docker Network Architecture
Network Namespace
Each Docker network operates in its own network namespace, providing isolation:
# View network namespaces
sudo ip netns list
# Docker creates namespaces in /var/run/docker/netns/
sudo ls /var/run/docker/netns/
Container Network Interface (CNI)
Docker uses various network interfaces:
- veth pairs: Virtual ethernet connections
- docker0 bridge: Default bridge interface
- Network namespaces: Isolation mechanism
Inspect Default Networks
# List all networks
docker network ls
# Inspect default bridge
docker network inspect bridge
Bridge Network
The bridge network is the default network driver for containers on a single host. Docker creates a virtual bridge (docker0) and connects containers to it via virtual ethernet pairs.
Default Bridge Network
When you run a container without specifying a network, it connects to the default bridge:
# Run container on default bridge
docker run -d --name web1 nginx
# Inspect container network
docker inspect web1 | grep IPAddress
Limitations of Default Bridge:
- Containers communicate via IP addresses only
- No automatic DNS resolution by container name
- All containers share same bridge (less isolation)
User-Defined Bridge Networks
Custom bridge networks provide better isolation and features:
# Create custom bridge network
docker network create my-bridge
# Create with custom subnet
docker network create \
--driver bridge \
--subnet 172.18.0.0/16 \
--gateway 172.18.0.1 \
my-custom-bridge
# Run containers on custom bridge
docker run -d --name web --network my-bridge nginx
docker run -d --name api --network my-bridge node:18-alpine
Advantages:
- Automatic DNS resolution by container name
- Better isolation between applications
- Custom IP address management
- On-the-fly container connections/disconnections
Bridge Network Configuration
# Create bridge with advanced options
docker network create \
--driver bridge \
--subnet 10.10.0.0/16 \
--ip-range 10.10.10.0/24 \
--gateway 10.10.0.1 \
--opt "com.docker.network.bridge.name"="my-bridge" \
--opt "com.docker.network.bridge.enable_icc"="true" \
--opt "com.docker.network.bridge.enable_ip_masquerade"="true" \
--opt "com.docker.network.driver.mtu"="1500" \
advanced-bridge
Container Communication on Bridge
# Create network and containers
docker network create app-network
docker run -d --name database --network app-network postgres:15-alpine
docker run -d --name backend --network app-network node:18-alpine
# Test connectivity from backend to database
docker exec backend ping database
docker exec backend nslookup database
Port Publishing
Expose container ports to host:
# Publish to random host port
docker run -d -P nginx
# Publish to specific port
docker run -d -p 8080:80 nginx
# Bind to specific interface
docker run -d -p 127.0.0.1:8080:80 nginx
# Publish multiple ports
docker run -d -p 8080:80 -p 8443:443 nginx
# Publish UDP port
docker run -d -p 53:53/udp dns-server
Static IP Assignment
# Create network with subnet
docker network create --subnet 172.20.0.0/16 static-net
# Run container with static IP
docker run -d \
--name web \
--network static-net \
--ip 172.20.0.10 \
nginx
Bridge Network Example
Complete example with multiple services:
# Create network
docker network create \
--driver bridge \
--subnet 172.25.0.0/16 \
--gateway 172.25.0.1 \
web-app-net
# Database container
docker run -d \
--name postgres \
--network web-app-net \
--ip 172.25.0.10 \
-e POSTGRES_PASSWORD=secret \
postgres:15-alpine
# Redis cache
docker run -d \
--name redis \
--network web-app-net \
--ip 172.25.0.11 \
redis:alpine
# Backend API
docker run -d \
--name api \
--network web-app-net \
--ip 172.25.0.20 \
-e DATABASE_URL=postgres://[email protected]:5432/app \
-e REDIS_URL=redis://172.25.0.11:6379 \
my-api:latest
# Frontend (with port publishing)
docker run -d \
--name frontend \
--network web-app-net \
-p 8080:80 \
my-frontend:latest
Host Network
The host network mode removes network isolation between container and host. The container uses the host's network stack directly.
Using Host Network
# Run container with host network
docker run -d --network host nginx
# Container uses host's ports directly
# No need for -p flag
When to Use Host Network
Advantages:
- Maximum network performance (no NAT overhead)
- No port mapping required
- Access to host network interfaces directly
Disadvantages:
- No network isolation
- Port conflicts with host services
- Reduced security
- Not portable across hosts
Use Cases
# Network monitoring tool
docker run -d --network host --name monitor netdata/netdata
# High-performance applications
docker run -d --network host redis:alpine
# Tools requiring host network access
docker run -it --network host nicolaka/netshoot
Host Network Example
# Run application on host network
docker run -d \
--name web-server \
--network host \
-e PORT=8080 \
my-app:latest
# Access directly on host:8080
curl http://localhost:8080
Important: Host network is only available on Linux. On Mac/Windows, it behaves differently due to Docker Desktop's VM architecture.
Overlay Network
Overlay networks enable communication between containers across multiple Docker hosts. Primarily used with Docker Swarm for orchestration.
Prerequisites for Overlay
- Docker Swarm must be initialized
- Ports opened between hosts:
- TCP 2377 (cluster management)
- TCP/UDP 7946 (node communication)
- UDP 4789 (overlay network traffic)
Initialize Docker Swarm
# On manager node
docker swarm init --advertise-addr <MANAGER-IP>
# On worker nodes (use token from init output)
docker swarm join --token <TOKEN> <MANAGER-IP>:2377
Create Overlay Network
# Create overlay network
docker network create \
--driver overlay \
--subnet 10.0.0.0/24 \
--gateway 10.0.0.1 \
my-overlay
# Create overlay with encryption
docker network create \
--driver overlay \
--opt encrypted \
secure-overlay
# Attachable overlay (for standalone containers)
docker network create \
--driver overlay \
--attachable \
app-overlay
Deploy Services on Overlay
# Create service on overlay network
docker service create \
--name web \
--network my-overlay \
--replicas 3 \
nginx
# Create multi-tier application
docker service create \
--name database \
--network my-overlay \
postgres:15-alpine
docker service create \
--name api \
--network my-overlay \
--replicas 5 \
my-api:latest
Overlay Network with Docker Compose
version: '3.8'
services:
web:
image: nginx
deploy:
replicas: 3
networks:
- overlay-net
api:
image: my-api:latest
deploy:
replicas: 5
networks:
- overlay-net
database:
image: postgres:15-alpine
networks:
- overlay-net
networks:
overlay-net:
driver: overlay
attachable: true
Deploy stack:
docker stack deploy -c docker-compose.yml myapp
Overlay Network Example
Complete multi-host setup:
# On Swarm manager
docker network create \
--driver overlay \
--subnet 10.1.0.0/16 \
--opt encrypted=true \
production-overlay
# Deploy web tier (3 replicas across nodes)
docker service create \
--name web \
--network production-overlay \
--replicas 3 \
--publish published=80,target=80 \
nginx
# Deploy API tier (5 replicas)
docker service create \
--name api \
--network production-overlay \
--replicas 5 \
my-api:latest
# Deploy database (single replica on manager)
docker service create \
--name postgres \
--network production-overlay \
--constraint node.role==manager \
--mount type=volume,source=db-data,target=/var/lib/postgresql/data \
postgres:15-alpine
Macvlan Network
Macvlan assigns MAC addresses to containers, making them appear as physical devices on the network. Useful for legacy applications expecting to be on physical network.
Create Macvlan Network
# Create macvlan network
docker network create \
--driver macvlan \
--subnet 192.168.1.0/24 \
--gateway 192.168.1.1 \
--opt parent=eth0 \
macvlan-net
Run Container on Macvlan
# Run with specific MAC and IP
docker run -d \
--name legacy-app \
--network macvlan-net \
--ip 192.168.1.100 \
legacy-image:latest
802.1Q VLAN Trunking
# Create macvlan with VLAN tagging
docker network create \
--driver macvlan \
--subnet 192.168.10.0/24 \
--gateway 192.168.10.1 \
--opt parent=eth0.10 \
macvlan-vlan10
Macvlan Use Cases
- Legacy applications requiring layer 2 connectivity
- Network monitoring and security tools
- Applications needing direct network access
- Integration with existing network infrastructure
Limitations:
- Cannot communicate with host (by design)
- Requires promiscuous mode on some networks
- Cloud providers often block macvlan
None Network
Disables networking completely. Container has only loopback interface.
Using None Network
# Run container with no network
docker run -d --network none alpine
# Verify no network interfaces
docker exec <container> ip addr show
Use Cases
- Maximum isolation for security-sensitive workloads
- Batch processing containers needing no network
- Testing network-free scenarios
Container Networking
Connect Container to Multiple Networks
# Create two networks
docker network create frontend
docker network create backend
# Run container on frontend
docker run -d --name app --network frontend nginx
# Connect same container to backend
docker network connect backend app
# Verify connections
docker inspect app | grep Networks -A 20
Disconnect Container from Network
# Disconnect from network
docker network disconnect backend app
Container Network Aliases
# Create network
docker network create app-net
# Run with network alias
docker run -d \
--name web1 \
--network app-net \
--network-alias webapp \
nginx
docker run -d \
--name web2 \
--network app-net \
--network-alias webapp \
nginx
# Both containers accessible via 'webapp' (round-robin DNS)
docker run --rm --network app-net alpine nslookup webapp
Network Commands
Essential Network Commands
# List networks
docker network ls
# Create network
docker network create my-network
# Inspect network
docker network inspect my-network
# Connect container to network
docker network connect my-network container-name
# Disconnect container
docker network disconnect my-network container-name
# Remove network
docker network rm my-network
# Remove unused networks
docker network prune
Advanced Inspection
# Get network ID
docker network ls -q -f name=my-network
# Format output
docker network inspect --format='{{range .Containers}}{{.Name}} {{end}}' my-network
# Get container IP on network
docker inspect \
--format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \
container-name
Network Information
# View container's networks
docker inspect container-name | grep Networks -A 20
# View all containers on network
docker network inspect my-network
# Get gateway
docker network inspect --format='{{.IPAM.Config}}' my-network
DNS and Service Discovery
Automatic DNS Resolution
Containers on user-defined networks can resolve each other by name:
# Create network and containers
docker network create app-net
docker run -d --name db --network app-net postgres:15-alpine
docker run -d --name api --network app-net my-api:latest
# API can connect to database using hostname 'db'
docker exec api ping db
docker exec api nslookup db
Custom DNS Configuration
# Run container with custom DNS
docker run -d \
--name web \
--dns 8.8.8.8 \
--dns 8.8.4.4 \
--dns-search example.com \
nginx
# Set DNS in daemon.json
sudo nano /etc/docker/daemon.json
Add:
{
"dns": ["8.8.8.8", "8.8.4.4"],
"dns-search": ["example.com"]
}
DNS Round Robin
# Create multiple containers with same network alias
docker network create lb-net
docker run -d --name web1 --network lb-net --network-alias web nginx
docker run -d --name web2 --network lb-net --network-alias web nginx
docker run -d --name web3 --network lb-net --network-alias web nginx
# DNS queries round-robin across containers
docker run --rm --network lb-net alpine nslookup web
Network Security
Network Isolation
# Create isolated networks for different applications
docker network create app1-net
docker network create app2-net
# App1 containers
docker run -d --name app1-web --network app1-net nginx
docker run -d --name app1-db --network app1-net postgres
# App2 containers (isolated from app1)
docker run -d --name app2-web --network app2-net nginx
docker run -d --name app2-db --network app2-net postgres
Network Encryption
# Create encrypted overlay network
docker network create \
--driver overlay \
--opt encrypted=true \
secure-overlay
Disable Inter-Container Communication
# Create network with ICC disabled
docker network create \
--driver bridge \
--opt com.docker.network.bridge.enable_icc=false \
isolated-bridge
Firewall Rules with iptables
Docker manages iptables automatically, but you can add custom rules:
# View Docker iptables rules
sudo iptables -t nat -L -n
# Add custom rule (example)
sudo iptables -I DOCKER-USER -i ext_if ! -s 192.168.1.0/24 -j DROP
Production Best Practices
Use User-Defined Networks
# Don't use default bridge
# Create application-specific networks
docker network create \
--driver bridge \
--subnet 172.28.0.0/16 \
production-app
Network Naming Convention
# Use descriptive names
docker network create prod-frontend
docker network create prod-backend
docker network create prod-database
Limit Network Exposure
# Only publish necessary ports
docker run -d \
-p 127.0.0.1:5432:5432 \
--name database \
--network backend \
postgres
Use Network Aliases for Service Discovery
version: '3.8'
services:
web:
image: nginx
networks:
frontend:
aliases:
- webserver
- www
Monitor Network Traffic
# Install network monitoring tools
docker run -d \
--name monitor \
--network host \
--cap-add NET_ADMIN \
nicolaka/netshoot
# Use tcpdump in container
docker exec -it monitor tcpdump -i eth0
Document Network Architecture
# docker-compose.yml with clear network structure
version: '3.8'
networks:
frontend:
driver: bridge
ipam:
config:
- subnet: 172.28.1.0/24
backend:
driver: bridge
ipam:
config:
- subnet: 172.28.2.0/24
database:
driver: bridge
internal: true # No external access
ipam:
config:
- subnet: 172.28.3.0/24
Troubleshooting
Container Cannot Connect
# Verify container is on correct network
docker inspect container-name | grep Networks -A 10
# Check network connectivity
docker exec container-name ping target-container
# Verify DNS resolution
docker exec container-name nslookup target-container
# Check network configuration
docker network inspect network-name
Port Conflict
# Find process using port
sudo netstat -tulpn | grep :8080
sudo lsof -i :8080
# Check Docker port mappings
docker ps --format "table {{.Names}}\t{{.Ports}}"
Network Not Found
# List all networks
docker network ls
# Recreate network
docker network rm old-network
docker network create new-network
Cannot Remove Network
# Find containers using network
docker network inspect network-name | grep Name
# Stop and remove containers
docker stop $(docker ps -q --filter network=network-name)
docker rm $(docker ps -aq --filter network=network-name)
# Remove network
docker network rm network-name
DNS Resolution Issues
# Check DNS settings
docker exec container-name cat /etc/resolv.conf
# Test DNS
docker exec container-name nslookup google.com
# Use custom DNS
docker run --dns 8.8.8.8 --dns 8.8.4.4 image-name
Network Performance Issues
# Check MTU settings
docker network inspect network-name | grep MTU
# Adjust MTU
docker network create --opt com.docker.network.driver.mtu=1450 my-net
# Test bandwidth
docker run -it --rm networkstatic/iperf3 iperf3 -c server-ip
Debug Network
# Use netshoot for debugging
docker run -it --rm --network container:target-container nicolaka/netshoot
# Inside netshoot, use tools:
ip addr show
ip route
netstat -tulpn
tcpdump -i eth0
Conclusion
Docker networking provides flexible, isolated network environments for containers. Understanding bridge, host, overlay, and other network modes is essential for building scalable, secure applications.
Key Takeaways
- Bridge Networks: Default for single-host, use user-defined bridges for DNS
- Host Network: Maximum performance but no isolation
- Overlay Networks: Multi-host communication for Swarm clusters
- Network Isolation: Use separate networks for security
- Service Discovery: Automatic DNS resolution in user-defined networks
- Production Ready: Use encryption, monitoring, and proper isolation
Quick Reference
# Network Management
docker network create my-net # Create network
docker network ls # List networks
docker network inspect my-net # Inspect network
docker network rm my-net # Remove network
docker network prune # Remove unused
# Container Networking
docker run --network my-net nginx # Run on network
docker network connect my-net container # Connect to network
docker network disconnect my-net container # Disconnect
docker run -p 8080:80 nginx # Publish port
# Network Types
docker network create --driver bridge my-bridge # Bridge network
docker run --network host nginx # Host network
docker network create --driver overlay my-overlay # Overlay network
Next Steps
- Practice: Create different network topologies
- Secure: Implement network isolation strategies
- Monitor: Set up network traffic monitoring
- Scale: Deploy overlay networks with Swarm
- Optimize: Tune network performance for your workload
- Document: Maintain network architecture diagrams
- Test: Implement network chaos testing
Docker networking is fundamental to container orchestration. Master these concepts to build robust, scalable containerized applications.


