Docker Networks: Connecting Multiple Containers
Running a single container is great for experiments, but real applications often involve multiple containers working together. For example:
- A web server container connecting to a database container
- A frontend container talking to a backend API container
- Multiple microservices sharing data or messaging
To make this happen, Docker provides networks, which control how containers communicate with each other and the outside world.
Understanding Docker’s Default Networks
Docker creates a few networks automatically:
- bridge – the default network for standalone containers
- host – containers share the host’s network stack
- none – container has no network
Most beginner projects rely on bridge networks, which provide isolated networking between containers while still allowing outgoing internet connections.
Bridge Networks: The Standard Choice
A bridge network is like a private virtual switch inside Docker. Containers on the same bridge can talk to each other using container names as hostnames.
Example:
docker network create my_bridge
docker run -d --name db --network my_bridge mysql
docker run -d --name api --network my_bridge my_api_image
Here:
- Both
dbandapiare on the samemy_bridgenetwork - The
apicontainer can reach the database by usingdb:3306 - No extra port exposure is required for internal communication
Bridge networks are isolated from the host by default, which is good for security.
Container-to-Container Communication
Once containers are on the same network, they can reach each other using names instead of IPs:
ping dbinside the API container will reach the database container- Service discovery is built-in — Docker automatically assigns names and DNS entries
This eliminates the need to hardcode IP addresses, which can change every time a container restarts.
Exposing Ports: Communicating with the Outside World
Containers often need to be accessed from outside Docker. This is done by mapping container ports to host ports:
docker run -d -p 8080:80 my_web_image
- Port
80inside the container is mapped to port8080on the host - You can now visit
http://localhost:8080to reach the web service
You can also combine port mapping with networks to allow some containers to talk internally while others are exposed externally.
User-Defined Networks
Instead of using the default bridge network, you can create user-defined networks, which offer:
- Easier service discovery
- More isolation and security
- Better control over traffic routing
Example:
docker network create frontend_net
docker network create backend_net
docker run -d --name frontend --network frontend_net my_frontend
docker run -d --name backend --network backend_net my_backend
You can then selectively connect containers to multiple networks if needed.
Docker Compose and Networking
When using Docker Compose, networks are handled automatically:
- Each service is placed on a default network
- Services can communicate by service name
- Exposed ports are mapped as defined in the
docker-compose.ymlfile
Example docker-compose.yml snippet:
services:
web:
image: my_web
ports:
- "8080:80"
db:
image: mysql
The web service can reach the db service just by using db:3306.
Best Practices for Container Networking
- Use user-defined bridge networks for multi-container applications.
- Avoid exposing unnecessary ports to the host — keep internal services private.
- Name your containers and services meaningfully for easier communication.
- Use Docker Compose for orchestrating multi-container networks in development.
- Consider overlay networks when scaling across multiple Docker hosts.
Small Networks, Big Impact
Docker networking might seem complex at first, but it’s really about deciding which containers can talk to each other and which are exposed externally.
- Bridge networks for isolated communication
- Port mapping for host access
- User-defined networks for clarity and control
- Compose for orchestrating everything
Once you understand these building blocks, connecting multiple containers becomes straightforward, and your containerized applications can grow from single experiments to full-fledged multi-service systems.