1.10 Docker Networking
Overview
Docker networking controls how containers communicate with each other, with the host, and with the outside world. Docker creates three networks automatically on installation: bridge, host, and none.
Abstract
Every container is attached to a network at runtime. The default bridge network gives containers private internal IPs and allows port mapping for external access. The host network removes isolation between container and host. The none network fully isolates a container. User-defined bridge networks allow custom subnets and DNS-based container-to-container communication. Docker's embedded DNS server (127.0.0.11) enables containers to resolve each other by name rather than IP.
Why It Matters in Production
- Containers need to communicate (web β database, service β cache) without hardcoding IPs that change on restart
- Network isolation prevents unintended cross-container access in multi-tenant or microservice environments
- Port mapping and host network mode determine how services are exposed externally
- Understanding Docker DNS is essential β container IPs are dynamic, names are stable
Default Networks
Docker creates three networks automatically on installation:
| Network | Command | Behaviour |
|---|---|---|
bridge |
docker run ubuntu |
Default. Private internal network (172.17.x.x). Containers communicate via internal IP. Requires port mapping for external access. |
none |
docker run ubuntu --network=none |
No network interface. Fully isolated β no external or inter-container access. |
host |
docker run ubuntu --network=host |
Shares the host's network stack. No port mapping needed, but ports are shared across all containers. |
Bridge Network
The default bridge network (docker0) assigns IPs in the 172.17.0.0/16 range:
Docker Host
ββββββββββββββββββββββββββββββββββ
β Web (172.17.0.2) β
β Web (172.17.0.3) β
β Web (172.17.0.4) β
β Web (172.17.0.5) β
β β docker0 (172.17.0.1) β
ββββββββββββββββββββββββββββββββββ
Containers on the default bridge can reach each other via internal IP. To expose a container externally, map a port:
Host Network
The container shares the host's network directly β no isolation, no port mapping required:
docker run --network=host my-web-app
# Port 5000 in the container is immediately accessible as port 5000 on the host
Host Network Limitation
Because all containers share the host's ports, you cannot run two containers that bind the same port when using --network=host.
None Network
User-Defined Networks
By default, Docker only creates one internal bridge network. To isolate groups of containers on separate internal networks, create custom networks:
Docker Host
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Web (172.17.0.2) βββ docker0 (172.17.0.1) β β default bridge
β Web (172.17.0.4) β
β β
β Web (182.18.0.3) βββ docker0 (182.18.0.1) β β custom network
β Web (182.18.0.2) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Containers on different networks are isolated β they cannot communicate unless explicitly connected.
List Networks
NETWORK ID NAME DRIVER SCOPE
dba0fb9370fe bridge bridge local
46d476b87cd9 customer-isolated-network bridge local
6de685cec1ce docker_gwbridge bridge local
e29d188b4e47 host host local
zmzho7vsb9rm ingress overlay swarm
d9f1169510d6 none null local
d371b4009142 simplewebappdocker_default bridge local
Inspecting Container Network Settings
Look for the NetworkSettings section:
"NetworkSettings": {
"Bridge": "",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.6",
"MacAddress": "02:42:ac:11:00:06",
"Networks": {
"bridge": {
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.6",
"MacAddress": "02:42:ac:11:00:06"
}
}
}
Embedded DNS
Docker includes a built-in DNS server that runs at 127.0.0.11 on every Docker host. Containers can resolve each other using container names instead of IP addresses.
Docker Host
βββββββββββββββββββββββββββββββββββββββββββ
β web (172.17.0.2) mysql (172.17.0.3) β
β β docker0 (172.17.0.1) β
β β
β DNS Server (127.0.0.11) β
β web β 172.17.0.2 β
β mysql β 172.17.0.3 β
βββββββββββββββββββββββββββββββββββββββββββ
Use container names in application connection strings β not IPs:
# Don't use β IP may change on restart
mysql.connect("172.17.0.3")
# Do use β resolved by Docker DNS
mysql.connect("mysql")
DNS works reliably on user-defined networks
Docker's embedded DNS resolves container names on user-defined bridge networks. On the default bridge network, name resolution is not guaranteed β use custom networks for production service discovery.
Example Commands
How Docker Implements Networking
Docker uses Linux network namespaces to isolate each container's network stack, and virtual Ethernet pairs (veth) to connect containers to the bridge. Each container sees its own network interface, routing table, and IP stack β fully isolated from other containers at the kernel level.
Best Practices
Best Practices
- Always use user-defined bridge networks for multi-container applications β they support DNS-based name resolution, unlike the default bridge.
- Reference services by container name, not IP β IPs are reassigned on restart, names are stable.
- Use
--network=nonefor containers that process data with no need for network access (batch jobs, transformations) to reduce attack surface. - Segment unrelated workloads onto separate custom networks to enforce isolation without firewall rules.
- Use Docker Compose β it automatically creates a user-defined network per project and wires up DNS for all services.
Security Best Practices
Security
- Avoid
--network=hostin production unless absolutely required β it removes all network isolation and exposes the container to the full host network stack. - Do not rely on the default bridge network for service discovery β it does not provide reliable DNS resolution between containers by name.
- Use custom networks to isolate sensitive services β a database container should only be on a network shared with the app that needs it, not the default bridge shared by all containers.
- Restrict inter-container traffic by not placing untrusted containers on the same network.
- Avoid hardcoding internal IPs in application configs β use DNS names that Docker resolves dynamically.
Do and Don't
| β Do | β Don't |
|---|---|
| Use user-defined networks for multi-container apps | Rely on the default bridge for DNS name resolution |
Connect containers by name (mysql, redis) |
Hardcode container IPs in application configs |
Use --network=none for isolated workloads |
Use --network=host unless there is a specific need |
Inspect network settings with docker inspect |
Guess which IP a container has after a restart |
| Create per-application custom networks | Put all containers on one shared bridge |
Common Mistakes
Common Mistakes
- Using default bridge and expecting DNS to work β the default
bridgenetwork does not support container name resolution; use a user-defined network. - Hardcoding container IPs β IPs from the
172.17.x.xpool are reassigned dynamically; always use container names. - Running two services on the same port with
--network=hostβ since the host's port namespace is shared, only one container can bind a given port at a time. - Not inspecting network settings after deploy β
docker inspectis the first tool to reach for when containers cannot communicate. - Forgetting to attach a container to the right network β a container only resolves names of other containers on the same network.
Troubleshooting
# List all networks
docker network ls
# Inspect a network (see connected containers and subnet)
docker network inspect bridge
# Inspect a container's IP and network attachment
docker inspect <container_name> | grep -A 20 '"NetworkSettings"'
# Test connectivity between containers (exec into one)
docker exec -it web ping mysql
# Check DNS resolution inside a container
docker exec -it web nslookup mysql
# Attach a running container to an additional network
docker network connect custom-isolated-network web
# Disconnect a container from a network
docker network disconnect bridge web
# Remove an unused network
docker network rm custom-isolated-network
Quick Recap
- Docker creates three default networks:
bridge(default),host,none - The default bridge network assigns IPs in
172.17.0.0/16; containers communicate via internal IP hostnetwork removes isolation β container shares the host's ports directlynonenetwork fully isolates a container- User-defined networks allow custom subnets and enable DNS-based name resolution
- Docker's embedded DNS server runs at
127.0.0.11β containers resolve each other by name - Use
docker network create,docker network ls, anddocker inspectto manage and debug networks - Docker networking uses Linux network namespaces and virtual Ethernet pairs under the hood
Interview / Revision Notes
- What are the three default Docker networks?
bridge,host,none - Default network for a container?
bridgeβ IP assigned in the172.17.0.0/16range - How do containers talk to each other on bridge? Via internal IPs or container names (on user-defined networks)
- What is the Docker embedded DNS address?
127.0.0.11 - Why not use container IPs for service discovery? IPs can change on restart; container names are stable and resolved by DNS
- Difference between bridge and host network? Bridge isolates the container with its own IP; host shares the host's network stack with no isolation
- How to create a custom network?
docker network create --driver bridge --subnet <CIDR> <name> - How does Docker implement network isolation? Linux network namespaces per container, connected via virtual Ethernet (veth) pairs
- When would you use
--network=none? For batch/data processing containers that require no network access - How to inspect a container's network settings?
docker inspect <container>β look atNetworkSettings