Docker is an essential tool for modern software development, providing a simple and efficient way to package applications into containers that can be run consistently across different environments. One of the core components of Docker is its networking capabilities, which are key to ensuring that containers can communicate with each other and the outside world.
In this article, we’ll explore Docker networking: its concepts, components, and how to manage and configure Docker networks to ensure your containerized applications run smoothly.
What is Docker Networking?
Docker networking is the system that allows Docker containers to communicate with each other, the host machine, and the external network. Since containers are isolated environments, Docker provides various network drivers and configurations to ensure that containers can connect and work together in a distributed system. Networking is one of the most critical aspects of containerized applications, especially when deploying multi-container applications or microservices.
Docker Networking Modes
Docker provides several network modes to configure how containers communicate with each other and the outside world. Below are the most commonly used Docker network modes:
Bridge Network (Default Network)
The bridge network is Docker’s default network mode for containers that are not explicitly connected to any other network. In this mode, Docker creates a virtual bridge on the host machine (usually docker0) and connects containers to it.
- How it works:
- Docker creates a virtual Ethernet bridge on the host (typically called docker0).
- Each container gets its own private IP address (usually within a subnet like 172.17.x.x).
- Containers can communicate with each other through this virtual network (via the bridge).
- Containers can also access the outside world (i.e., the internet) by using Network Address Translation (NAT).
- You will need to do host:container port mapping to access server app running in a container.
- Use Case:
- When you want containers to be isolated from the host but still need them to communicate with each other and the external world.
- When you need a separate, Docker-controlled network for your containers that won’t interfere with the host’s network configuration.
# create a custom network
docker network create <custom_network_name>
# use your custom network
docker run –it –network=<custom_network_name> ubuntu:latest /bin/bash
# delete your custom network
docker network rm <custom_network_name>
# delete all unused custom-networks
docker network prune
Using docker compose
services:
snippet-box:
image: pawelmalak/snippet-box:latest
container_name: snippet-box
volumes:
- ./snipdb:/app/data
ports:
- 127.0.0.1:5000:5000
restart: unless-stopped
networks:
- <custom_network_name_Use-here>
networks:
<custom_network_name_use-here>:
external: true
name: <custom_network_name>
Host Network
In host mode, a container shares the network namespace of the host machine. This means that the container can directly access the host’s network interfaces and the ports exposed by the container will be directly mapped to the host.
- How it works:
- The container uses the host’s network stack for its networking needs.
- The container does not get its own IP address. Instead, it shares the host’s IP address.
- This mode is typically used when you want the container to have full access to the host’s network interfaces without any form of isolation.
- Use cases:
- When the container needs to use specific network resources from the host directly.
- When you want to minimize networking overhead (as there is no NAT or bridge involved).
- For performance-sensitive applications where minimal networking overhead is required (e.g., high-performance networking or applications that need direct access to the host’s interfaces).
docker run -d --name <container-name> --network host <image-name>
Using docker compose
version: '3'
services:
nginx:
image: nginx
container_name: nginx-container
network_mode: host
Macvlan Network
Macvlan allows you to assign a MAC address to a container, making it appear as a physical device on the network. This enables direct communication with the network, bypassing Docker’s networking stack.
How it works: Each container gets its own IP address and can communicate with devices on the local network. This is often used when you want to expose containers directly to the LAN.
# Creating the macvlan network
docker network create -d macvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
-o parent=eth0 macvlan_network
# using the
docker run -d --name macvlan-nginx --network macvlan_network nginx
using docker compose file
services:
nginx:
image: nginx
container_name: nginx-container
networks:
mymacvlan:
ipv4_address: 192.168.1.2
networks:
mymacvlan:
external: true
name: mymacvlan
None Network
In this mode, containers are completely isolated from the host network and other containers. The container doesn’t get an IP address and can’t communicate with any other container or external system.
How it works:
- No Network Interface: The container does not get any network interfaces, so it has no access to the outside world or to other containers.
- No IP Address: Since there is no network interface, the container doesn’t get an IP address.
- No Communication: The container can’t communicate with any other container or the host unless specific configuration or network interfaces are added manually. This means there’s no DNS, no access to external services, and no inter-container communication.
- Only Local Access: The container can still access the local file system and the process namespace of the host, but it is fully isolated from any external networks.
docker run --network none my_image
How Does the None Network Compare with Other Network Drivers?
Let’s compare none with the more common Docker networking drivers: bridge, host, and macvlan.
Feature | None Network Driver | Bridge Network Driver | Host Network Driver | Macvlan Network Driver |
Network Isolation | Complete isolation (no network) | Moderate isolation (via a bridge) | No isolation (container shares the host’s network) | Strong isolation (container gets its own MAC and IP) |
IP Address | No IP address assigned | Private IP address (e.g., 172.17.x.x) | Shares the host’s IP address | Unique IP assigned to the container |
Access to Host | No access to the host network | Can access the host via the bridge | Full access to the host network | Cannot access the host network by default |
Communication Between Containers | No communication allowed | Allowed within the bridge network | Allowed, as containers share the host network | Allowed within the same macvlan network |
Use Case | When no networking is needed | Default mode for isolated container networking | For containers that need direct access to host network | When containers need to appear as separate physical devices |
Port Binding | Not applicable | Required to access the container from the host | Not required (container shares the host’s network) | Not required (container gets its own IP) |
Security | Very secure (no access to anything) | Moderate security (isolated from host and other networks) | Less secure (container shares network with host) | Stronger isolation, no access to host by default |
Routing/NAT | No routing or NAT | NAT is applied for communication with the outside world | No NAT needed, as container shares the host network | No NAT, communication is direct, but requires network configuration |
Performance | Very low overhead (no networking) | Low overhead (NAT and bridge) | Very low overhead (direct access to host network) | Low overhead (direct Layer 2 communication) |
Container Hostname
Print hostname of the container
docker inspect -f '{{ .Config.Hostname }}' <container-id>
Set the hostname of a container
docker run --hostname my-nginx-container -d nginx
Set dns server along with custom hostname
docker run --name test-container -it \
--hostname=test-con.example.com \
--dns=8.8.8.8 \
ubuntu /bin/bash
Set hostname in docker-compose file
services:
myservice:
image: myimage
hostname: my-container-hostname
List and inspect network
docker network ls
# inspect driver
## bridge , host and none are created by default by docker deamon
docker network inspect bridge
docker network inspect <custom-network>
Adding basic network Security to your container
Publishing container ports is insecure by default. Meaning, when you publish a container’s ports it becomes available not only to the Docker host, but to the outside world as well.
If you include the localhost IP address (127.0.0.1, or ::1) with the publish flag, only the Docker host and its containers can access the published container port.
docker run -p 127.0.0.1:8080:80 nginx
Using docker compose
services:
snippet-box:
image: pawelmalak/snippet-box:latest
container_name: snippet-box
volumes:
- ./snipdb:/app/data
ports:
- 127.0.0.1:5000:5000
restart: unless-stopped
networks:
- <custom_network_name_Use-here>
networks:
<custom_network_name_use-here>:
external: true
name: <custom_network_name>
Conclusion
Docker networking is a powerful feature that facilitates seamless communication between containers, the host machine, and external networks. By understanding the different types of network drivers and when to use them, you can optimize your Docker configurations for both security and performance. Whether you’re deploying a simple application or managing a complex multi-container system, mastering Docker networking is essential for creating efficient, scalable, and secure containerized environments.