Docker Networking¶
🌐 Learning Objectives
- Understand Docker network types
- Configure container networking
- Set up port mapping
- Troubleshoot network issues
Understand Docker's networking capabilities and how containers communicate.
Network Best Practices
Use user-defined bridge networks instead of the default bridge. Containers on custom networks can communicate by name (DNS resolution). Isolate services with separate networks for better security.
Port Mapping
The format is -p host_port:container_port. Use specific host ports in production. For development, you can let Docker assign random ports with -p container_port and check with docker port.
Network Types¶
Docker provides several network types, each with different characteristics and use cases.
Default Networks¶
Docker automatically creates three networks when installed:
What you'll see:
NETWORK ID NAME DRIVER SCOPE
abc123def456 bridge bridge local
def456ghi789 host host local
ghi789jkl012 none null local
The three default networks: 1. bridge: Default network for containers (most common) 2. host: Uses host's network directly (Linux only) 3. none: No networking (completely isolated)
Inspect a network:
What this shows: - Network configuration (subnet, gateway) - Connected containers - Network driver details - IP address ranges
Example output (abbreviated):
{
"Name": "bridge",
"Driver": "bridge",
"IPAM": {
"Config": [{"Subnet": "172.17.0.0/16"}]
},
"Containers": {
"web": {
"IPv4Address": "172.17.0.2/16"
}
}
}
Bridge Network (Default)¶
The bridge network is Docker's default network. Containers on this network can communicate with each other and the outside world.
What happens:
- Container is automatically connected to bridge network
- Gets an IP address (usually 172.17.0.x)
- Can access internet (if host can)
- Can communicate with other containers on bridge
Get container IP address:
What you'll see:
Limitations of default bridge: - Containers can't resolve each other by name - Must use IP addresses for communication - Less isolation between containers - Not ideal for multi-container applications
Example - Communication by IP:
# Container 1
docker run -d --name web1 nginx
# Get IP of web1
WEB1_IP=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web1)
# Container 2 can reach web1 by IP
docker run -it --rm alpine wget -O- http://$WEB1_IP
Why Default Bridge Has Limitations
The default bridge network doesn't have automatic DNS resolution. This means containers can't find each other by name - you must use IP addresses. For better networking, use custom bridge networks.
User-Defined Bridge Network¶
Custom bridge networks provide better features than the default bridge, especially automatic DNS resolution.
Create a custom network:
What this does:
- Creates a new bridge network named
mynetwork - Uses bridge driver (default)
- Gets its own subnet (usually 172.18.0.0/16, 172.19.0.0/16, etc.)
- Isolated from default bridge network
Run containers on custom network:
# Run containers on custom network
docker run -d --name web1 --network mynetwork nginx
docker run -d --name web2 --network mynetwork nginx
What happens:
- Both containers join mynetwork
- Each gets an IP address on this network
- Key feature: Automatic DNS resolution by container name
Test DNS resolution:
What this does:
web1can resolveweb2by name (not just IP)- Docker's built-in DNS resolves
web2to its IP address - Ping works using the container name
Example output:
PING web2 (172.18.0.3) 56(84) bytes of data.
64 bytes from web2.mynetwork (172.18.0.3): icmp_seq=1 ttl=64 time=0.123 ms
Real-world example - Database connection:
# Create network
docker network create app-network
# Run database
docker run -d --name db --network app-network \
-e POSTGRES_PASSWORD=secret postgres
# Run application (can connect using 'db' as hostname)
docker run -d --name app --network app-network \
-e DATABASE_URL=postgres://db:5432/mydb \
my-app
Why this works:
- Application uses db as hostname (not IP address)
- Docker DNS resolves db to the database container's IP
- No need to know or hardcode IP addresses
- If database container restarts and gets new IP, DNS automatically updates
Benefits of Custom Networks
- Automatic DNS resolution: Containers can find each other by name
- Better isolation: Separate networks for different applications
- Easy management: Attach/detach containers with
docker network connect/disconnect - Security: Isolate services (frontend network, backend network, database network)
- Scalability: Easy to add more containers to the network
Host Network¶
# Use host network (Linux only)
docker run -d --name web --network host nginx
# Container uses host's network directly
# No port mapping needed
Warning
Host network bypasses Docker's network isolation. Use with caution.
None Network¶
# Container with no network
docker run -d --name isolated --network none alpine sleep 3600
# Container has no network interfaces
docker exec isolated ip addr
Network Drivers¶
Bridge Driver¶
# Create bridge network with custom subnet
docker network create \
--driver bridge \
--subnet=172.20.0.0/16 \
--gateway=172.20.0.1 \
mybridge
Overlay Network (Swarm)¶
# Initialize swarm
docker swarm init
# Create overlay network
docker network create \
--driver overlay \
--attachable \
myoverlay
Macvlan Network¶
# Create macvlan network
docker network create \
--driver macvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
-o parent=eth0 \
mymacvlan
Use Case
Macvlan allows containers to appear as physical devices on the network.
Port Mapping¶
Basic Port Mapping¶
# Map container port to host port
docker run -d -p 8080:80 nginx
# Map to specific interface
docker run -d -p 127.0.0.1:8080:80 nginx
# Map random host port
docker run -d -p 80 nginx
docker port <container_id>
Port Range Mapping¶
# Map port range
docker run -d -p 8000-8010:8000-8010 myapp
# Map UDP port
docker run -d -p 53:53/udp dns-server
Container Communication¶
Linking Containers (Legacy)¶
# Legacy linking (deprecated)
docker run -d --name db postgres
docker run -d --name app --link db:database myapp
Deprecated
Use networks instead of links.
Network Communication¶
# Create network
docker network create app-network
# Run database
docker run -d --name db --network app-network \
-e POSTGRES_PASSWORD=secret postgres
# Run application
docker run -d --name app --network app-network \
-e DATABASE_URL=postgres://db:5432/mydb \
myapp
Network Inspection¶
View Network Details¶
# Inspect network
docker network inspect mynetwork
# Show network connections
docker network inspect mynetwork --format '{{range .Containers}}{{.Name}} {{end}}'
Container Network Info¶
# View container network settings
docker inspect <container> | grep -A 20 NetworkSettings
# Execute network commands in container
docker exec <container> ip addr
docker exec <container> netstat -tulpn
DNS Resolution¶
Custom DNS¶
# Use custom DNS server
docker run -d --dns 8.8.8.8 --dns 8.8.4.4 nginx
# Disable DNS
docker run -d --network none nginx
DNS Search Domains¶
Network Troubleshooting¶
Common Issues¶
# Check if containers can reach each other
docker exec container1 ping container2
# Test port connectivity
docker exec container1 nc -zv container2 80
# View network traffic
docker exec container1 tcpdump -i eth0
# Check DNS resolution
docker exec container1 nslookup container2
Debug Network Problems¶
# List all networks
docker network ls
# Inspect network configuration
docker network inspect bridge
# Check container IP
docker inspect <container> | grep IPAddress
# Test connectivity
docker run --rm --network mynetwork \
alpine ping -c 3 container_name
Best Practices¶
- Use user-defined networks instead of default bridge
- Isolate services with separate networks
- Use DNS names instead of IP addresses
- Limit network exposure with firewall rules
- Monitor network traffic in production
Exercises¶
- Create a custom bridge network and connect multiple containers
- Set up a web server and database on the same network
- Configure port mapping for a multi-service application
- Troubleshoot a network connectivity issue between containers
Previous: Advanced Dockerfiles | Next: Volumes and Data Management