Docker Networking Deep Dive: Bridge, Host, Overlay, and Macvlan
Master Docker networking. Bridge networks, DNS resolution, port publishing, overlay networks for Swarm, macvlan for direct LAN access, and troubleshooting...
Docker Networking Fundamentals
Docker networking is one of the most misunderstood aspects of containers. Understanding how containers communicate is essential for building reliable, secure infrastructure.
Docker Compose defines your entire application stack in a single YAML file.
Network Drivers
Docker provides four main network drivers:
1. Bridge Network (Default)
Bridge is the default network driver. Containers on the same bridge network can communicate by container name (DNS resolution). Containers on different bridge networks are isolated.
# Create a custom bridge network
docker network create --driver bridge app-net
# Run containers on the same network
docker run -d --name api --network app-net my-api:latest
docker run -d --name db --network app-net postgres:16
# The api container can reach the db container by name:
# postgresql://db:5432/myapp
Docker Compose automatically creates a bridge network:
# docker-compose.yml
services:
api:
image: my-api:latest
networks:
- app-net
db:
image: postgres:16
networks:
- app-net
redis:
image: redis:7
networks:
- app-net
networks:
app-net:
driver: bridge
All three containers can reach each other by service name: api, db, redis.
How bridge networking works under the hood:
Host Network Namespace
├── eth0 (192.168.1.100) ← Physical interface
├── docker0 (172.17.0.1) ← Default bridge
├── br-abc123 (172.18.0.1) ← Custom bridge (app-net)
│ ├── vethXXX → api (172.18.0.2)
│ ├── vethYYY → db (172.18.0.3)
│ └── vethZZZ → redis (172.18.0.4)
└── iptables NAT rules ← Port publishing
Each container gets a virtual ethernet interface (veth pair) connected to the bridge. Docker runs an embedded DNS server that resolves container names to their IPs.
Get more insights on Tutorials
Join 2,000+ engineers who get our weekly deep-dives. No spam, unsubscribe anytime.
2. Host Network
Host networking removes network isolation. The container shares the host's network stack directly.
docker run -d --name nginx --network host nginx:alpine
# Nginx listens on port 80 of the host directly
# No port mapping needed (or possible)
# docker-compose.yml
services:
cloudflared:
image: cloudflare/cloudflared:latest
network_mode: host
# No ports: section needed - it binds to host directly
When to use host networking:
- Maximum network performance (no NAT overhead)
- Services that need to bind to specific host interfaces
- Networking tools (tcpdump, monitoring agents)
- When port mapping causes issues (some protocols)
Downsides: No port isolation, containers can conflict, cannot run multiple instances of the same service.
3. Overlay Network (Docker Swarm)
Overlay networks span multiple Docker hosts, allowing containers on different machines to communicate as if on the same LAN.
# Initialize Swarm
docker swarm init
# Create overlay network
docker network create --driver overlay --attachable app-overlay
# Services on different nodes can communicate
docker service create --name api --network app-overlay my-api:latest
docker service create --name db --network app-overlay postgres:16
Docker Compose brings up your entire stack with a single command.
4. Macvlan Network
Macvlan gives each container its own MAC address on the physical network. Containers appear as physical devices on the LAN.
# Create macvlan network
docker network create -d macvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
-o parent=eth0 \
lan-net
# Container gets a real LAN IP
docker run -d --name pihole \
--network lan-net \
--ip 192.168.1.50 \
pihole/pihole:latest
When to use macvlan: IoT devices, network appliances (Pi-hole, DHCP server), or when containers need to be directly accessible on the LAN.
DNS Resolution in Docker
Docker's embedded DNS server (127.0.0.11) handles service discovery:
# From inside a container
nslookup db
# Server: 127.0.0.11
# Name: db
# Address: 172.18.0.3
# Docker Compose also creates aliases
nslookup postgres
# Resolves to the 'db' container if that's the service name
DNS aliases with network aliases:
services:
database:
image: postgres:16
networks:
app-net:
aliases:
- db
- postgres
- pg
# Container reachable as: database, db, postgres, pg
Port Publishing
Port publishing maps host ports to container ports via iptables NAT:
services:
api:
image: my-api:latest
ports:
# host:container
- "3000:3000" # All interfaces
- "127.0.0.1:3001:3001" # Localhost only
- "8080:80/tcp" # Explicit TCP
- "8443:443/udp" # UDP
Security tip: Bind to 127.0.0.1 for services that should only be accessible locally or through a reverse proxy:
services:
# Only Traefik is exposed
traefik:
ports:
- "80:80"
- "443:443"
# Internal services - no ports published
api:
# No ports: section. Only reachable via Docker network (through Traefik)
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`api.example.com`)"
Multi-Network Architecture
Isolate services by putting them on different networks:
Free Resource
Free Cloud Architecture Checklist
A 47-point checklist covering security, scalability, cost optimization, and disaster recovery for production cloud environments.
services:
traefik:
networks:
- frontend
- backend # Can reach both
api:
networks:
- backend
- database # Can reach db, not frontend directly
db:
networks:
- database # Only reachable from database network
redis:
networks:
- database
networks:
frontend: # External-facing services
backend: # Application services
database: # Data layer (most isolated)
Troubleshooting Docker Networking
# Inspect network details
docker network inspect app-net
# List all networks
docker network ls
# Check container's network settings
docker inspect --format='{{json .NetworkSettings.Networks}}' container-name
# Test connectivity from inside a container
docker exec -it api ping db
docker exec -it api nslookup db
docker exec -it api wget -qO- http://db:5432
# Debug with a network tools container
docker run -it --rm --network app-net nicolaka/netshoot
# Inside netshoot:
nslookup api
curl http://api:3000/health
tcpdump -i eth0 port 5432
iperf3 -c db -p 5201
# Check iptables rules (port publishing)
sudo iptables -t nat -L DOCKER -n
# Check if port is published correctly
ss -tlnp | grep 3000
Container orchestration distributes workloads across multiple nodes for resilience and scale.
Common Networking Mistakes
Using default bridge: The default bridge does not support DNS resolution between containers. Always create a custom bridge network.
Publishing unnecessary ports: Only publish ports that need external access. Internal services should communicate via Docker networks.
Hardcoding IPs: Container IPs change on restart. Always use container names (DNS).
Ignoring network isolation: Put databases on a separate network from external-facing services.
Forgetting DNS cache: Some containers cache DNS. If a container IP changes, others may have stale entries. Use the embedded DNS resolver.
At TechSaaS, we use a single custom bridge network (padc-net) for all our Docker containers. Traefik is the only container with published ports (80). All 50+ services communicate via container names over the bridge network, and databases are accessible only from within the Docker network. This is the simplest and most secure networking setup for a single-host deployment.
Related Service
Cloud Solutions
Let our experts help you build the right technology strategy for your business.
Need help with tutorials?
TechSaaS provides expert consulting and managed services for cloud infrastructure, DevOps, and AI/ML operations.
We Will Build You a Demo Site — For Free
Like it? Pay us. Do not like it? Walk away, zero complaints. You will spend way less than hiring developers or any agency.
No spam. No contracts. Just a free demo.