Table of Contents
Understanding Container to Container Communication
Container to container communication is about how running containers talk to each other directly over the network. At this point you already know what Docker networking is in general and what bridge networks are. In this chapter you will see how containers discover each other, how names and IP addresses work, and how different network setups affect communication.
IP Addresses vs Container Names
Every container attached to a Docker network receives its own internal IP address. If you run docker inspect on a container that is connected to a user defined bridge network, you can see this IP inside the Networks section.
Although containers can talk to each other using these IP addresses, you should not rely on them. Docker can change container IPs when containers are stopped and started again, or when networks are recreated.
Docker provides a better way through automatic DNS based on container names. When containers are attached to the same user defined bridge network, Docker runs an internal DNS service. Each container can resolve the name of other containers on that network. For example, if you start a container with --name api on a user defined network, other containers on that network can connect to it using the hostname api.
Always use container names or service names for communication, not container IP addresses.
Communication on the Default Bridge Network
The default bridge network is created by Docker when it starts. Containers attached to this network can communicate by IP address. However, name resolution on the default bridge network is very limited. By default, container names on the default bridge network are not resolved through Docker's DNS the way they are on user defined bridge networks.
This means that if you rely on container names to connect containers to each other, you should avoid the default bridge network and create your own bridge network instead. Custom bridge networks give you predictable name based discovery, which is much easier to work with and maintain.
Benefits of User Defined Bridge Networks
User defined bridge networks are where Docker's container to container communication features become convenient. When multiple containers are attached to the same user defined bridge network, they gain several advantages that directly affect how they communicate.
First, they get automatic DNS for container names. Each container can reach another by using its name as a hostname. There is no need to manually edit configuration files with IP addresses.
Second, isolation between different networks becomes simple. Containers on one user defined bridge network cannot directly talk to containers on another user defined bridge network unless you attach them to both. This helps you separate unrelated parts of an application, such as keeping a database only reachable from the backend service that needs it.
Third, you get predictable behavior when containers are recreated. If a container with the same name is recreated and attached to the same network, other containers can still reach it using the same name, even if its internal IP changes.
Discovering Other Containers by Name
Name based discovery is the core of practical container to container communication. When a container tries to connect to db:5432 or redis:6379, Docker's internal DNS resolves db or redis to the IP of the matching container on the same user defined network.
This works automatically as long as:
The containers share the same user defined bridge network.
Each container has a unique name on that network.
The application inside the container is configured to use the other container's name as the host.
If two containers have the same name, Docker will not allow them to be created on the same Docker host, so name collisions are avoided at the Docker level. It is still your job to use clear and meaningful names that match the roles of your containers, such as web, api, or database.
Connecting Multiple Containers to a Network
A single container can be attached to one or more networks. When a container is attached to multiple networks, it receives a separate IP for each network. It can talk to containers on any of those networks, and it can be used as a bridge between otherwise isolated groups.
This is useful when you want to expose some containers to more than one group of services. For example, you might attach a logging container to both an app network and a monitoring network so that it can collect logs from application services and be monitored by separate tools.
When a container participates in multiple networks, name resolution still happens per network. Containers on each network can resolve the names of other containers on that same network. They cannot automatically see containers on networks to which they are not attached.
Linking to External Services
Sometimes, a container needs to communicate with a service that is not running as a container, for example a legacy database running directly on a virtual machine. In this case, container to container communication rules do not fully apply, but similar ideas help.
Containers can reach external services by using DNS names or IP addresses, just like regular applications. If the external service is accessible on the host or on another server, and routing and firewall rules allow it, containers can connect to it without special Docker features. From the container's point of view, this is just another host on the network.
You can place containers that coordinate external calls on a user defined bridge network, and inside those containers you use the normal hostnames or IPs of the external services. This keeps internal communication between containers clear and separate from the paths that leave Docker networks.
Port Mapping vs Internal Container Communication
Port mapping is about connecting external clients to containers. It exposes container ports on the Docker host so browsers and other tools can reach them from outside. For container to container communication inside a Docker network, port mapping is not required.
Containers on the same network talk to each other using the container's internal ports. If a database listens on port 5432 in its container, other containers on the same network can use port 5432 directly without any -p or --publish configuration.
Containers on the same Docker network do not need port mapping to communicate with each other. Port mapping is only for traffic that enters or leaves Docker from the host or external networks.
This distinction is important when you design your setup. You can keep many services completely internal and only expose a small number of entry points to the outside world.
Security and Isolation Considerations
Container to container communication is powerful but can also create accidental exposure inside your Docker host. If you attach too many containers to the same network, any container on that network can potentially reach any other, unless you add extra restrictions outside of Docker.
By using multiple user defined networks and attaching each container only to the networks it needs, you can restrict communication paths. For example, you can keep a database on a network that only the backend service can access, while the frontend web container is on a separate network where it only talks to the backend.
This pattern keeps your architecture clear and reduces accidental dependencies between unrelated containers. It also prevents a compromised container that should not access the database from directly connecting to it.
Name Stability and Container Lifecycle
Containers are often stopped, removed, and recreated during development and deployment. This lifecycle has a direct effect on communication.
If you recreate a container with the same name on the same user defined network, other containers can continue to use that name to reach it. The IP address might change, but the name remains stable. Docker's internal DNS updates the mapping automatically.
If you change container names, you may need to update the configuration of other containers so they use the new names. In larger setups, this problem is often solved through higher level tools that manage containers and services for you, but at the Docker level the key idea is to rely on meaningful, stable names for your containers on each network.
Practical Naming and Communication Patterns
In real projects, container to container communication usually follows a few predictable patterns.
Application code often uses environment variables that hold hostnames for dependent services. Inside the container, those variables are set to the names of other containers on the same network. For example, DB_HOST=db or CACHE_HOST=redis. This keeps network details separate from your source code and lets you change container names or networks with less friction.
You can also group containers by role and network. A typical pattern is to have a network for the public facing web part and another for internal components like databases and background workers. Containers that need to talk across both groups can be attached to both networks, while purely internal components stay on only one.
As you grow more comfortable with Docker networking, you will find that managing container to container communication is mainly about designing clear network boundaries, choosing stable names, and relying on Docker's DNS on user defined networks.