Networks in Docker: Bridge vs NAT vs Host
Overview
Docker provides different network modes for containers, each with specific use cases and characteristics. Understanding the differences between Bridge, NAT, and Host networking is crucial for designing containerized applications.
Docker Network Types
1. Bridge Network (Default)
Definition: Bridge network is Docker’s default network mode. Containers on a bridge network can communicate with each other, and Docker provides isolation from the host network.
How it Works:
- Docker creates a virtual bridge (usually
docker0) - Containers get their own network namespace
- Containers receive private IP addresses (172.17.0.0/16 by default)
- Port mapping is required to access containers from host
Characteristics:
- Isolation from host network
- Containers can communicate with each other
- Port mapping needed for external access
- Default network mode
- Good for most use cases
2. NAT (Network Address Translation)
Note: NAT is not a separate network mode but a mechanism used by Bridge networks. Docker uses NAT to map container ports to host ports.
How it Works:
- Docker uses iptables for NAT
- Maps container ports to host ports
- Allows external access to containers
- Masks container IPs behind host IP
Characteristics:
- Automatic port translation
- Security through isolation
- Multiple containers can use same internal ports
- External access via host IP:port
3. Host Network
Definition: Host network mode removes network isolation between container and host. Container uses host’s network directly.
How it Works:
- Container shares host’s network stack
- No network namespace isolation
- Container uses host’s IP address
- No port mapping needed
Characteristics:
- No isolation from host
- Best performance (no NAT overhead)
- Direct access to host network
- Port conflicts possible
- Less secure
Detailed Comparison
Bridge Network
Configuration:
# Default bridge network
docker run -d --name container1 nginx
# Custom bridge network
docker network create mybridge
docker run -d --name container1 --network mybridge nginx
docker-compose.yml:
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "8080:80" # Host:Container port mapping
networks:
- mynetwork
db:
image: postgres:13
networks:
- mynetwork
networks:
mynetwork:
driver: bridge
Network Inspection:
# List networks
docker network ls
# Inspect network
docker network inspect bridge
# Create custom bridge
docker network create --driver bridge mybridge
# Connect container to network
docker network connect mybridge container1
Port Mapping:
# Map host port 8080 to container port 80
docker run -d -p 8080:80 nginx
# Map specific host IP
docker run -d -p 127.0.0.1:8080:80 nginx
# Map random host port
docker run -d -p 80 nginx
docker port container_name # Check mapped port
Container Communication:
# Containers on same bridge can communicate by name
docker run -d --name web --network mybridge nginx
docker run -d --name app --network mybridge myapp
# App can reach web at http://web:80
NAT (Network Address Translation)
How Docker Uses NAT:
# When you run:
docker run -d -p 8080:80 nginx
# Docker creates NAT rules:
# iptables -t nat -A DOCKER -p tcp --dport 8080 -j DNAT --to-destination 172.17.0.2:80
# iptables -t nat -A POSTROUTING -s 172.17.0.2 -j MASQUERADE
View NAT Rules:
# View iptables NAT rules
sudo iptables -t nat -L -n
# View Docker NAT rules
sudo iptables -t nat -L DOCKER -n
NAT Flow:
External Request → Host:8080 → NAT → Container:80
Container Response → Container:80 → NAT → Host:8080 → External
Multiple Containers with NAT:
# Each container can use port 80 internally
docker run -d -p 8080:80 nginx:1
docker run -d -p 8081:80 nginx:2
docker run -d -p 8082:80 nginx:3
# External access:
# http://host:8080 → nginx:1
# http://host:8081 → nginx:2
# http://host:8082 → nginx:3
Host Network
Configuration:
# Use host network
docker run -d --network host nginx
# Container uses host's network directly
# No port mapping needed
# Access at http://localhost:80
docker-compose.yml:
version: '3.8'
services:
web:
image: nginx:alpine
network_mode: host
# No ports section needed
Characteristics:
# Container sees host's network interfaces
docker run --network host --rm alpine ip addr
# Container uses host's IP
docker run --network host nginx
# Accessible at http://<host-ip>:80
# Port conflicts
# If host already uses port 80, container will fail
Comparison Table
| Feature | Bridge | NAT | Host |
|---|---|---|---|
| Isolation | Yes | Yes | No |
| Port Mapping | Required | Automatic | Not needed |
| Performance | Good | Good (NAT overhead) | Best |
| Security | High | High | Low |
| IP Address | Private (172.17.x.x) | Private + NAT | Host IP |
| Container Communication | By name/IP | By name/IP | By name/IP |
| External Access | Via port mapping | Via port mapping | Direct |
| Port Conflicts | No (different IPs) | No (different mappings) | Yes (same ports) |
| Use Case | Most applications | Most applications | High performance, low latency |
Use Cases
Bridge Network Use Cases
- Multi-Container Applications:
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "80:80"
networks:
- app-network
api:
image: my-api:latest
networks:
- app-network
db:
image: postgres:13
networks:
- app-network
networks:
app-network:
driver: bridge
- Development Environments:
# Isolated development environment
docker network create dev-network
docker run -d --network dev-network --name db postgres
docker run -d --network dev-network --name app myapp
- Microservices:
services:
service1:
networks:
- microservices-network
service2:
networks:
- microservices-network
networks:
microservices-network:
driver: bridge
NAT Use Cases
- Port Mapping for Services:
# Web server
docker run -d -p 80:80 nginx
# Database (internal only)
docker run -d -p 5432:5432 postgres
# Multiple instances
docker run -d -p 8080:80 nginx:1
docker run -d -p 8081:80 nginx:2
- Load Balancing:
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
depends_on:
- web1
- web2
web1:
image: myapp:latest
# No port mapping (internal only)
web2:
image: myapp:latest
# No port mapping (internal only)
Host Network Use Cases
- High-Performance Applications:
# Low latency requirements
docker run --network host my-high-performance-app
- Network Monitoring Tools:
# Tools that need to see host network
docker run --network host --privileged network-monitor
- Single Container on Host:
# When only one container needs a port
docker run --network host nginx
Security Considerations
Bridge Network Security
Pros:
- Network isolation
- Containers isolated from host
- Can control inter-container communication
Cons:
- Port mapping exposes services
- Need firewall rules
Best Practices:
# Only expose necessary ports
docker run -d -p 127.0.0.1:8080:80 nginx # Only localhost
# Use firewall
sudo ufw allow 8080/tcp
# Isolate networks
docker network create --internal isolated-network
NAT Security
Pros:
- Masks container IPs
- Can restrict access via firewall
- Port mapping control
Cons:
- NAT rules complexity
- Potential for misconfiguration
Best Practices:
# Bind to specific interface
docker run -d -p 127.0.0.1:8080:80 nginx
# Use firewall
sudo iptables -A INPUT -p tcp --dport 8080 -j DROP
Host Network Security
Pros:
- Simpler networking
- No NAT overhead
Cons:
- No network isolation
- Container can access host network
- Port conflicts
- Less secure
Best Practices:
# Only use when necessary
# Avoid for untrusted containers
# Use with caution in production
Performance Comparison
Bridge Network Performance
# Good performance with some overhead
# NAT translation adds minimal latency
# Suitable for most applications
# Benchmark
docker run --rm --network bridge alpine ping -c 10 8.8.8.8
Host Network Performance
# Best performance
# No NAT overhead
# Direct network access
# Benchmark
docker run --rm --network host alpine ping -c 10 8.8.8.8
Performance Impact:
- Bridge: ~1-2ms overhead per packet
- Host: No overhead
- Difference: Negligible for most apps, significant for high-frequency networking
Common Interview Questions and Answers
Q1: What is the difference between Bridge, NAT, and Host networking in Docker?
Bridge Network:
- Default network mode
- Containers get private IPs (172.17.0.0/16)
- Isolated from host network
- Port mapping required for external access
- Containers can communicate by name
NAT:
- Not a separate mode, but mechanism used by Bridge
- Translates container ports to host ports
- Uses iptables for port mapping
- Allows external access via host IP:port
Host Network:
- Container uses host’s network directly
- No isolation from host
- No port mapping needed
- Best performance, less secure
- Port conflicts possible
Q2: When should you use Bridge network vs Host network?
Use Bridge Network when:
- Need network isolation
- Running multiple containers
- Security is important
- Standard application deployment
- Most use cases
Use Host Network when:
- Need maximum performance
- Low latency requirements
- Network monitoring tools
- Single container per host
- Performance critical applications
Example:
# Bridge: Standard web app
docker run -d -p 8080:80 nginx
# Host: High-performance app
docker run --network host high-performance-app
Q3: How does NAT work in Docker?
Docker uses iptables for NAT:
- Port Mapping:
docker run -d -p 8080:80 nginx
- Docker Creates NAT Rules:
# DNAT: Destination NAT (incoming)
iptables -t nat -A DOCKER -p tcp --dport 8080 \
-j DNAT --to-destination 172.17.0.2:80
# MASQUERADE: Source NAT (outgoing)
iptables -t nat -A POSTROUTING -s 172.17.0.2 \
-j MASQUERADE
- Flow:
- External request → Host:8080
- NAT translates → Container:80
- Response → Container:80
- NAT translates → Host:8080 → External
Q4: How do containers communicate in Bridge network?
Containers on same bridge network can communicate:
- By Container Name (DNS):
docker network create mybridge
docker run -d --name web --network mybridge nginx
docker run -d --name app --network mybridge myapp
# App can reach web at http://web:80
- By IP Address:
# Get container IP
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web
# Use IP directly
docker exec app curl http://172.17.0.2:80
- Docker Compose (automatic):
services:
web:
networks:
- mynetwork
app:
networks:
- mynetwork
# Can access web at http://web:80
Q5: What are the security implications of Host network mode?
Security concerns:
- No Isolation: Container can access host network directly
- Port Conflicts: Container ports conflict with host ports
- Host Access: Container can bind to host ports
- Network Visibility: Container sees all host network traffic
Mitigations:
# Only use for trusted containers
# Avoid for untrusted images
# Use firewall rules
# Monitor network activity
Example:
# Dangerous: Untrusted container on host network
docker run --network host untrusted-image
# Safer: Use bridge network
docker run -d -p 8080:80 trusted-image
Q6: How do you create a custom bridge network?
Custom bridge network:
# Create bridge network
docker network create mybridge
# Create with options
docker network create \
--driver bridge \
--subnet 192.168.1.0/24 \
--gateway 192.168.1.1 \
mybridge
# Use in docker run
docker run -d --name container1 --network mybridge nginx
docker run -d --name container2 --network mybridge nginx
# Use in docker-compose
version: '3.8'
services:
web:
networks:
- mybridge
networks:
mybridge:
driver: bridge
ipam:
config:
- subnet: 192.168.1.0/24
Q7: How does port mapping work in Bridge network?
Port mapping process:
- Map Port:
docker run -d -p 8080:80 nginx
# Host port 8080 → Container port 80
- Multiple Mappings:
docker run -d -p 8080:80 -p 8443:443 nginx
# Map multiple ports
- Specific Host IP:
docker run -d -p 127.0.0.1:8080:80 nginx
# Only accessible from localhost
- Random Port:
docker run -d -p 80 nginx
# Docker assigns random host port
docker port container_name # Check assigned port
Q8: What is the default bridge network in Docker?
Default bridge network:
# Created automatically
docker network ls
# Shows "bridge" network
# Characteristics:
# - Name: bridge
# - Driver: bridge
# - Subnet: 172.17.0.0/16 (default)
# - Gateway: 172.17.0.1
# Inspect
docker network inspect bridge
# Containers use it by default
docker run nginx # Uses bridge network
Limitations:
- Containers can’t resolve each other by name
- Need to use IP addresses or links
- Less isolation
Custom Bridge Benefits:
- Automatic DNS resolution
- Better isolation
- More control
Q9: How do you troubleshoot Docker networking issues?
Troubleshooting steps:
- List Networks:
docker network ls
docker network inspect <network>
- Check Container Network:
docker inspect <container> | grep -A 20 NetworkSettings
docker exec <container> ip addr
docker exec <container> ping <other-container>
- Test Connectivity:
# From container
docker exec container1 ping container2
docker exec container1 curl http://container2:80
# Check port mapping
docker port <container>
netstat -tuln | grep 8080
- View NAT Rules:
sudo iptables -t nat -L -n
sudo iptables -t nat -L DOCKER -n
- Network Logs:
docker logs <container>
docker network inspect <network> --verbose
Q10: What are the performance differences between network modes?
Performance comparison:
Bridge Network:
- Overhead: ~1-2ms per packet (NAT translation)
- Suitable for: Most applications
- Impact: Negligible for web apps
Host Network:
- Overhead: None
- Suitable for: High-performance apps
- Impact: Best for low-latency requirements
Benchmark Example:
# Bridge network
time docker run --rm --network bridge alpine ping -c 100 8.8.8.8
# Host network
time docker run --rm --network host alpine ping -c 100 8.8.8.8
When Performance Matters:
- High-frequency trading
- Real-time systems
- Low-latency requirements
- Network-intensive applications
Best Practices
- Use Bridge for Most Cases: Default choice for most applications
- Create Custom Networks: Better isolation and DNS resolution
- Minimize Port Exposure: Only expose necessary ports
- Use Host Network Sparingly: Only when performance is critical
- Implement Firewall Rules: Secure exposed ports
- Monitor Network Traffic: Track container communication
- Use Internal Networks: For containers that don’t need external access
- Document Network Architecture: Keep network topology documented
- Test Network Connectivity: Verify container communication
- Use Network Policies: Implement network segmentation
Summary
Bridge Network:
- Default, isolated, secure
- Port mapping required
- Good for most use cases
NAT:
- Mechanism used by Bridge
- Automatic port translation
- Enables external access
Host Network:
- Direct host network access
- Best performance
- Less secure, use with caution
Key Takeaways:
- Bridge is default and recommended for most cases
- NAT provides port mapping automatically
- Host network for performance-critical applications
- Security vs Performance trade-off
- Choose based on requirements
Interview angle
- “What are the network modes?” - bridge (default, isolated network with port publishing), host (shares the host stack, no isolation and no port mapping), none (no networking), and overlay for multi-host. Bridge is the default for good reason.
- “How do containers find each other?” - on a user-defined bridge network, by service name via the embedded DNS. The default bridge doesn’t provide name resolution, which is why Compose creates its own network.
- “When is host networking justified?” - when you need the host’s exact network stack or want to avoid the NAT hop for latency-sensitive or high-throughput workloads. The cost is losing isolation and port-conflict safety.