Docker Networking
How Container Networking Works
Docker networking enables containers to communicate with each other and the outside world. By default, containers are isolated-networking must be explicitly configured. Understanding Docker's networking model is crucial for multi-container applications.
Network Modes
graph TD
A["Docker Network Modes"] -->B["Bridge
Default"]
A -->C["Host
Direct Access"]
A -->D["Overlay
Swarm/K8s"]
A -->E["None
No Network"]
B -->B1["Container Network Namespace"]
C -->C1["Host Network Namespace"]
D -->D1["Multi-Host Network"]
E -->E1["Isolated Container"]
style B fill:#90EE90
style C fill:#FFD700
style D fill:#87CEEB
style E fill:#FFB6C6
Bridge Network (Default)
Containers connect through a virtual bridge. Each container gets its own IP address and can communicate with others on the same bridge.
# Create custom bridge network
docker network create my-network
# Run containers on the network
docker run --name web --network my-network -d nginx
docker run --name api --network my-network -d myapi:latest
# Containers communicate by name
# From api: curl http://web
Host Network
Container shares the host's network namespace. Direct access to host ports-no port mapping needed.
docker run --network host -d nginx
# Nginx runs on actual host port 80, not containerized
Use case: Performance-critical applications needing direct network access.
Overlay Network
For Docker Swarm and Kubernetes deployments. Enables communication across multiple hosts.
# Initialize Docker Swarm
docker swarm init
# Create overlay network
docker network create -d overlay my-overlay
# Services on overlay network can reach each other across hosts
None Network
Complete network isolation. Container cannot communicate with other containers or the host.
docker run --network none -d alpine sleep 1000
# No network access; useful for security isolation
Container Communication
Service Discovery by Name
In bridge networks, containers reference each other by service name:
# api service accessing database
FROM python:3.9-slim
WORKDIR /app
COPY . .
CMD ["python", "app.py"]
# Python connecting to database by container name
import psycopg2
conn = psycopg2.connect(
host="database", # Container name resolves to IP
database="myapp",
user="appuser"
)
Port Mapping
Expose container ports to the host.
# Container port 5000 accessible on host port 8000
docker run -p 8000:5000 myapp:latest
# Specify host IP and port
docker run -p 127.0.0.1:8000:5000 myapp:latest
Multi-Container Communication
A practical example with Docker Compose:
version: '3.8'
services:
frontend:
build: ./frontend
ports:
- "3000:3000"
api:
build: ./api
ports:
- "5000:5000"
depends_on:
- database
database:
image: postgres:15-alpine
environment:
- POSTGRES_PASSWORD=secret
Communication paths:
graph LR
FE["Frontend
:3000"] -->|http://api:5000| API["API
:5000"]
API -->|jdbc:postgresql://database| DB["Database
:5432"]
style FE fill:#e1f5ff
style API fill:#fff3e0
style DB fill:#e8f5e9
Network Configuration in Compose
version: '3.8'
services:
web:
image: nginx:latest
networks:
- frontend
api:
build: ./api
networks:
- frontend
- backend
db:
image: postgres:15-alpine
networks:
- backend
networks:
frontend:
driver: bridge
backend:
driver: bridge
Services on same network can reach each other by name. Services isolated to different networks cannot communicate directly.
DNS and Service Discovery
Docker's embedded DNS server (127.0.0.11:53) resolves container names to IP addresses.
# Query DNS
docker run --rm alpine nslookup database
# Returns IP address of 'database' container
Advanced DNS options:
# Custom hostname aliases
docker run --network my-network \
--hostname my-host \
--add-host db.example.com:172.20.0.2 \
myapp:latest
Network Troubleshooting
Check Network Status
# List all networks
docker network ls
# Inspect network details
docker network inspect my-network
# View container network settings
docker inspect --format='{{.NetworkSettings}}' container_name
Test Connectivity
# From inside container
docker exec web ping api
# DNS resolution test
docker exec web nslookup api
Common Issues and Solutions
| Issue | Cause | Solution |
|---|---|---|
| Containers can't reach each other | Different networks | Use same network or connect containers |
| Port already in use | Host port occupied | Use different port mapping |
| DNS resolution fails | Wrong container name | Verify container name in network |
| Slow communication | Network overhead | Use host network if performance critical |
Common Pitfalls
- Forgetting to create networks - Containers on default bridge have limited DNS features
- Hardcoding IP addresses - Always use container/service names
- Port mapping conflicts - Multiple containers trying to use same host port
- Allowing all traffic by default - Use network segmentation for security
- Not configuring firewall rules - Restrict inter-container communication unnecessarily
Key Takeaways
- Bridge networks (custom) provide reliable container-to-container communication via DNS by service name
- Each network mode (bridge, host, overlay, none) serves different use cases and performance requirements
- Port mapping exposes container ports to the host; internal communication uses container names
- Service discovery through DNS resolves container names to IP addresses automatically
- Network segmentation improves security by isolating services that shouldn't communicate
- Docker Compose automatically creates and manages networks for defined services
- Troubleshooting tools (inspect, exec, ping, nslookup) help diagnose networking issues
Next Steps: Implement custom bridge networks for new applications, verify DNS resolution between services, and establish network policies for inter-service communication in production.