Docker Networking Inside Containers Explained
Docker containers get their network access through a combination of Linux kernel features—network namespaces, virtual Ethernet pairs, and iptables—that together create an isolated yet connected environment. When you run a container with default settings, Docker attaches it to a bridge network, giving it its own IP address and routing traffic through a virtual switch on the host. This article explains exactly how that works, what each component does, and how to troubleshoot common networking issues.
Background: Why Containers Need Special Networking
Unlike virtual machines, containers share the host’s kernel and do not have their own physical network interface. To give each container a unique IP address and the ability to communicate with the outside world, Docker creates a virtual network stack. This stack is built from three main Linux primitives:
- Network namespaces – isolate the network stack (interfaces, routes, firewall rules) so each container sees only its own.
- Virtual Ethernet (veth) pairs – act like a cable connecting the container’s namespace to the host’s namespace.
- Bridge interfaces – act as a virtual switch on the host, forwarding traffic between containers and the outside.
These components work together to give every container a private IP address while hiding the complexity of the host’s actual network.
How the Default Bridge Network Works
When you run docker run without specifying a network, Docker creates a bridge named docker0 on the host (IP typically 172.17.0.1). Here is the step-by-step process when a container starts:
- Docker creates a new network namespace for the container.
- It creates a veth pair – one end placed inside the container namespace (eth0), the other attached to the bridge (vethXXXX).
- It assigns an IP address from the bridge subnet (e.g., 172.17.0.2) to the container’s eth0.
- It sets up a default route in the container pointing to the bridge IP (172.17.0.1) as the gateway.
- It configures iptables rules on the host to allow outbound traffic (masquerading) and inbound port forwarding.
When a container sends a packet to the internet, it goes: container eth0 → veth pair → bridge docker0 → host routing → out through the host’s physical interface. The host performs source NAT (masquerading) so the packet appears to come from the host’s IP.
Port Publishing and iptables
To let traffic from outside reach a container, you use -p 8080:80. This tells Docker to forward host port 8080 to container port 80. Docker implements this using iptables DNAT rules. For example, a rule like:
iptables -t nat -A DOCKER -p tcp --dport 8080 -j DNAT --to-destination 172.17.0.2:80
This rule is inserted in the DOCKER chain, which is called from the PREROUTING and OUTPUT chains. The result is that any packet arriving at the host on port 8080 gets its destination rewritten to the container’s IP and port. The container sees the original source IP (unless you enable IP masquerade), and the reply follows the connection tracking table back.
Other Network Drivers and Their Uses
Docker offers several network drivers beyond the default bridge:
- host – removes network isolation; the container uses the host’s network stack directly. Useful for performance but no port mapping or isolation.
- none – disables networking entirely; only a loopback interface exists.
- bridge – the default; also supports user-defined bridges with DNS resolution between containers.
- overlay – connects containers across multiple hosts (used with Docker Swarm or Kubernetes).
- macvlan – assigns a real MAC address to each container, making it appear as a physical device on the network.
For most single-host setups, the default bridge is sufficient. User-defined bridges add automatic DNS, so containers can refer to each other by name instead of IP.
Common Problems and How to Diagnose Them
Networking issues are among the most frequent Docker problems. Here are typical symptoms and their causes:
- Container cannot reach the internet – check if the host has internet, then inspect the container’s DNS settings (
/etc/resolv.conf). Often caused by missing iptables MASQUERADE rules or a misconfigured firewall. - Port mapping doesn’t work – verify the port is bound correctly with
docker port <container>. Ensure the host firewall allows the port. - Containers cannot talk to each other – on the default bridge, use IP addresses; on a user-defined bridge, use container names. Check that both are on the same network.
- DNS resolution fails – Docker’s embedded DNS (127.0.0.11) only works on user-defined networks. On the default bridge, containers use the host’s DNS settings.
Useful commands: docker network inspect to see details, docker exec <container> ip addr to view interfaces, and docker logs <container> for application-level errors.
Security Implications of Docker Networking
Network isolation is a key security boundary. The default bridge allows all outbound traffic and any container can reach any other container on the same bridge. For production, consider these practices:
- Use user-defined bridge networks to control inter-container communication.
- Expose only necessary ports; avoid
-p 0.0.0.0:80:80unless needed. - Do not use the host network driver unless absolutely required, as it bypasses isolation.
- Regularly audit iptables rules to ensure no unintended forwarding.
Remember that Docker’s default firewall rules are additive; if you have a host firewall (like UFW), you may need to adjust it to allow Docker traffic.
Comparison: Bridge vs Host vs Overlay
Choosing the right driver depends on your needs:
- Bridge – best for development and single-host deployments; provides isolation and port mapping.
- Host – best for performance-critical apps that need the host’s network directly; no NAT overhead.
- Overlay – required for multi-host networking, as in Docker Swarm or Kubernetes; encrypts traffic optionally.
For Kubernetes, the container network interface (CNI) replaces Docker’s networking. Kubernetes uses a pod concept where multiple containers share a single network namespace, and the CNI plugin (e.g., Calico, Flannel) sets up the actual networking.
Frequently Asked Questions
Why does my container have a 172.17.x.x IP address?
That is the default subnet for Docker’s bridge network. Docker reserves 172.17.0.0/16 for the default bridge. You can change it by editing /etc/docker/daemon.json with the bip option, but it is rarely necessary.
How do I make two containers talk to each other by name?
Create a user-defined bridge network (docker network create mynet) and run both containers with --network mynet. Docker’s embedded DNS will resolve container names to their IPs automatically.
Can I use the same port on multiple containers?
Yes, but only if you map different host ports. For example, -p 8080:80 for one container and -p 8081:80 for another. The host ports must be unique.
Why does localhost inside a container not reach the host?
Because each container has its own loopback interface. To reach the host, use the special hostname host.docker.internal (on Docker Desktop) or find the host’s IP on the bridge network (usually 172.17.0.1).
What is the difference between bridge and overlay networking?
Bridge networking works on a single host, while overlay networking spans multiple hosts. Overlay uses a virtual network layer (like VXLAN) to encapsulate packets, allowing containers on different machines to communicate as if on the same switch.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.