Docker Compose Networking¶
Network Basics in Compose¶
Docker Compose creates a default network for each project:
Default Network Behavior¶
Automatic DNS¶
Services can reach each other by name:
Automatic Network Naming¶
Network Isolation¶
Each compose project is isolated:
Custom Networks¶
Define Networks¶
services:
web:
networks:
- frontend
api:
networks:
- frontend
- backend
db:
networks:
- backend
networks:
frontend:
backend:
Network Options¶
networks:
frontend:
driver: bridge
driver_opts:
com.docker.network.bridge.name: br-frontend
backend:
driver: bridge
internal: true # No external access
ipam:
driver: default
config:
- subnet: 10.0.1.0/24
gateway: 10.0.1.1
Use External Network¶
Port Publishing in Compose¶
Basic Syntax¶
services:
web:
ports:
# Long syntax
- target: 80
published: 8080
protocol: tcp
mode: host
# Short syntax
- "80:80"
- "443:443"
Localhost Binding¶
Random Port¶
Network Aliases¶
services:
db:
networks:
backend:
aliases:
- database
- postgres
legacy-api:
networks:
backend:
aliases:
- api # Multiple services can share an alias
Static IPs¶
services:
web:
networks:
backend:
ipv4_address: 10.0.1.10
networks:
backend:
ipam:
config:
- subnet: 10.0.1.0/24
DNS Configuration¶
Custom DNS¶
Extra Hosts¶
Network Patterns¶
Frontend/Backend Pattern¶
services:
nginx:
image: nginx
ports:
- "80:80"
- "443:443"
networks:
- frontend
depends_on:
- app
app:
image: myapp
networks:
- frontend
- backend
depends_on:
- db
- redis
db:
image: postgres
networks:
- backend
volumes:
- db-data:/var/lib/postgresql/data
redis:
image: redis
networks:
- backend
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true
volumes:
db-data:
Microservices Pattern¶
services:
gateway:
image: kong
ports:
- "80:8000"
- "443:8443"
networks:
- public
- services
auth:
image: auth-service
networks:
- services
- data
users:
image: users-service
networks:
- services
- data
orders:
image: orders-service
networks:
- services
- data
postgres:
image: postgres
networks:
- data
redis:
image: redis
networks:
- data
networks:
public:
services:
internal: true
data:
internal: true
Shared Network Pattern¶
For services across multiple compose files:
# File: app1/docker-compose.yml
services:
web:
networks:
- shared
networks:
shared:
external: true
name: app-network
# File: app2/docker-compose.yml
services:
api:
networks:
- shared
networks:
shared:
external: true
name: app-network
Security Considerations¶
Minimize Published Ports¶
# BAD: Everything exposed
services:
web:
ports:
- "80:80"
db:
ports:
- "5432:5432" # Unnecessary!
redis:
ports:
- "6379:6379" # Unnecessary!
# GOOD: Only what's needed
services:
web:
ports:
- "80:80"
db:
# No ports - only network access
redis:
# No ports - only network access
Use Internal Networks¶
Localhost for Development¶
# Development override
# docker-compose.override.yml
services:
db:
ports:
- "127.0.0.1:5432:5432" # Localhost only
UFW Integration¶
With ufw-docker¶
With DOCKER-USER¶
# Allow compose services
iptables -I DOCKER-USER -i eth0 -p tcp --dport 80 -j ACCEPT
# Block database port explicitly
iptables -I DOCKER-USER -i eth0 -p tcp --dport 5432 -j DROP
Debugging Compose Networks¶
View Networks¶
Test Connectivity¶
# Enter container
docker compose exec web sh
# Test DNS
nslookup db
ping db
# Test port
nc -zv db 5432
View Container IPs¶
docker compose exec web ip addr
docker inspect myproject-web-1 -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'
Environment-Specific Configuration¶
Development¶
# docker-compose.override.yml (auto-loaded)
services:
web:
ports:
- "8080:80" # Different port for dev
db:
ports:
- "127.0.0.1:5432:5432" # Expose for debugging