
Docker Networking: Bridge, Host, Overlay & More
In this guide, I'll walk through all the major Docker network drivers: bridge, host, overlay, IPvlan, macvlan, and none. Understanding how containers communicate is essential when designing any Docker-based architecture, and picking the right driver can make a real difference in performance, security, and simplicity.
By the end, you'll know when to reach for each driver and how to configure them with practical, copy-paste-ready examples.
Prerequisites
- Docker installed on a Linux host (some drivers are Linux-only)
- Basic familiarity with networking concepts like subnets, gateways, and DNS
- Comfort with the command line
Goals
- Understand what each Docker network driver does and when to use it
- Set up user-defined bridge networks with DNS resolution
- Use Docker Compose to define networks declaratively
- Know the trade-offs between bridge, host, overlay, IPvlan, and macvlan drivers
Why Docker Networking Matters (and Why Not Kubernetes)
A common question is: why not just use Kubernetes for everything? If you only have one or a few applications to run, Kubernetes adds significant overhead. You'd need to manage kubelet, DNS, etcd, and various controllers. A standard 3-tier app (frontend clients, application logic, relational database) can run perfectly well on a single Linux server with Docker. Don't reach for Kubernetes unless you genuinely need it.
1. The Default Bridge Network
When you install Docker, it automatically creates a default bridge network (typically 172.17.0.0/16). Any container you start without specifying a network gets an IP from this range and can communicate with other containers on the same host.
What is a Bridge?
In traditional networking, a bridge connects multiple local area networks, splitting them into smaller collision domains to improve performance. In Docker, the bridge connects your host machine to the virtual network Docker creates for your containers. Think of it as a software switch sitting between your containers and the host's network stack.
Limitations of the Default Bridge
Docker itself doesn't recommend using the default bridge network in production. The biggest drawback: DNS is not supported. Containers can only reach each other by IP address, not by name. This makes service discovery painful and fragile, since container IPs can change every time a container restarts.
# List all Docker networks
docker network ls
# Inspect the default bridge network
docker network inspect bridge
# Run a container (with port forwarding for Mac users)
docker run -d --name myapp -p 8081:8080 your-image
# SSH into the container
docker exec -it myapp sh
# Try to reach another container by name — this will fail on the default bridge
curl http://myapp-v2:8080Note: The default bridge exists for backward compatibility. For anything beyond quick throwaway tests, always create a user-defined bridge instead.
2. User-Defined Bridge Networks (Recommended)
The fix for DNS limitations is simple: create your own bridge network. With a user-defined bridge, Docker runs an embedded DNS server that lets containers reach each other using their container name as a hostname. This is the recommended approach for multi-container applications on a single host.
# Create a custom bridge network
docker network create --subnet 10.0.0.0/24 --gateway 10.0.0.1 my-bridge-net
# Run containers attached to the custom network
docker run -d --name myapp --network my-bridge-net -p 8081:8080 your-image
docker run -d --name myapp-v2 --network my-bridge-net -p 8082:8080 your-image
# SSH into a container and use DNS to reach the other
docker exec -it myapp sh
curl http://myapp-v2:8080 # This works!Besides DNS, user-defined bridges also provide better isolation. Containers on different user-defined networks cannot communicate with each other by default, which gives you network segmentation out of the box.
Using Docker Compose
In practice, Docker Compose is the cleanest way to define this setup declaratively. Instead of running multiple docker network create and docker run commands, you describe the entire topology in a single file:
version: "3"
services:
myapp:
image: your-image
ports:
- "8081:8080"
networks:
- my-bridge-net
myapp-v2:
image: your-image
ports:
- "8082:8080"
networks:
- my-bridge-net
networks:
my-bridge-net:
driver: bridge
ipam:
config:
- subnet: 10.0.0.0/24docker-compose -f docker-compose.yml up -d
docker-compose -f docker-compose.yml down3. Host Network
With the host driver, the container shares the networking namespace of the host. There is no IP isolation and no port mapping required. From the outside world, it looks just like a regular application running directly on the server.
This matters for performance. Because the container bypasses Docker's NAT layer and the userland-proxy, you get lower latency and higher throughput. It's a good fit when the container binds to many ports, or when you need maximum network performance.
Key characteristics:
- Linux only (does not work on Mac or Windows)
- No NAT, no
userland-proxyoverhead - Best for high-throughput or many-port workloads
# Run a container using the host network
docker run -d --network host your-image
# Access it directly via the host's IP from another machine
curl http://<host-ip>:8080Because there's no port isolation, you can't run two containers bound to the same port (e.g., two services both on port 80). Plan your port allocations carefully when using this driver.
Note: On Docker Desktop for Mac and Windows,
--network hostdoesn't behave the same way as on Linux. The container runs inside a VM, so you won't get true host networking.
4. None (Isolated Network)
The none driver completely isolates the container. Only a loopback interface is created. No inbound or outbound network traffic is possible.
This is useful when a container has no reason to talk to the network. Batch processing jobs, data transformation pipelines, and security-sensitive workloads that should never make external calls are all good candidates.
docker run -d --network none your-image
# Check interfaces inside the container
docker exec -it <container> sh
ip addr # Only loopback (lo) is present5. IPvlan
IPvlan is a lightweight network virtualization technique that attaches containers directly to the host's network interface, no bridge required. Containers get an IP from the same subnet as the host, making them directly reachable by other machines on the network without any port mapping.
The reason this is useful is that it removes Docker's networking overhead entirely. The container appears as just another device on your physical network, which is ideal for environments where you want containers to participate in the existing network topology.
# Find your host network interface
ip link show
# Example: ens33 with host IP 192.168.50.55/24
# Create the IPvlan network
docker network create \
--driver ipvlan \
--subnet 192.168.50.0/24 \
--gateway 192.168.50.1 \
--opt parent=ens33 \
my-ipvlan-net
# Run a container — no port mapping needed
docker run -d --network my-ipvlan-net your-image
# From another host on the network
curl http://192.168.50.2:8080With IPvlan, the container shares the same MAC address as the host. This is an important distinction from macvlan (covered next), and it means IPvlan works well in environments where the switch or network has MAC address limits.
6. Macvlan
Macvlan is similar to IPvlan but assigns each container its own unique MAC address, making it appear as a fully separate physical device on the network. This is ideal for legacy applications or network monitoring tools that expect to be directly connected to the physical network.
# Create the macvlan network
docker network create \
--driver macvlan \
--subnet 192.168.50.0/24 \
--gateway 192.168.50.1 \
--opt parent=ens33 \
my-macvlan-net
# Run a container
docker run -d --network my-macvlan-net your-image
# Inspect the container — notice a different MAC address than the host
docker inspect <container>IPvlan vs. Macvlan at a Glance
| Feature | IPvlan | Macvlan |
|---|---|---|
| MAC address | Same as host | Unique per container |
| Use case | Modern lightweight networking | Legacy apps needing physical NIC appearance |
| Performance | Very high | Very high |
| MAC limits | No issue (shared MAC) | Can hit switch port MAC limits |
7. Overlay Network
The overlay driver creates a distributed network spanning multiple Docker hosts, allowing containers on different servers to communicate as if they were on the same local network. It works by encapsulating container traffic in VXLAN tunnels between hosts.
Overlay networks are most commonly used with Docker Swarm, where you need services running on different nodes to discover and talk to each other seamlessly.
# Initialize Docker Swarm on the manager node
docker swarm init
# On worker node(s), run the join command provided by swarm init
# On the manager, create an attachable overlay network
docker network create \
--driver overlay \
--attachable \
my-overlay-net
# Start a container on the manager
docker run -d --name app1 --network my-overlay-net your-image
# Start a container on the worker
docker run -d --name app2 --network my-overlay-net your-image
# From app2, reach app1 across hosts
docker exec -it app2 sh
curl http://app1:8080 # Works across different VMs!Tip: If you're managing containers at scale across many hosts in production, consider Kubernetes instead of Docker Swarm. Swarm works well for simpler setups, but Kubernetes is a more robust solution for large-scale orchestration.
Quick Reference: When to Use Which Driver
| Driver | Use Case | Linux Only? |
|---|---|---|
bridge (default) |
Quick local testing | No |
User-defined bridge |
Multi-container apps with DNS | No |
host |
High-performance, many ports | Yes |
none |
Batch jobs, isolated workloads | No |
ipvlan |
Direct LAN access, lightweight | Yes |
macvlan |
Legacy apps needing unique MAC | Yes |
overlay |
Multi-host container communication | Yes |
Conclusion
Docker gives you a network driver for nearly every scenario. For most single-host applications, a user-defined bridge is the right starting point: it gives you DNS, isolation, and works on all platforms. When you need raw performance and are running on Linux, the host driver removes all networking overhead. For multi-host communication, overlays handle the complexity of routing traffic between nodes.
IPvlan and macvlan are more specialized. They're most useful when containers need to sit directly on the physical network, either because existing infrastructure expects it or because you want to avoid Docker's NAT layer entirely.
The key takeaway is to match the driver to your actual requirements. Start simple with bridge networks, and only reach for the more advanced options when you have a concrete reason to do so.
Comments