Back to Blog
Lesson 23 of the Docker: Containers & Your First Image course
DevOpsAugust 10, 20264 min read

Multi-Container Networking: Mastering Docker Internal DNS

Learn how Docker handles internal networking, DNS resolution, and service isolation. Master container-to-container communication with real-world examples.

dockernetworkingdevopsdnscontainersbridge
Top view of colorful shipping containers at a bustling port in Jakarta, Indonesia.

Previously in this course, we explored Defining Service Relationships in Docker Compose, where we ensured services started in the correct order. In this lesson, we add the "glue" that allows those services to talk to each other: Multi-Container Networking.

When you run multiple containers—like an application and a database—they need a private, secure way to exchange data without exposing themselves to the public internet. Docker solves this by creating isolated virtual networks that provide built-in service discovery via internal DNS.

Understanding the Docker Bridge Network

By default, when you run docker-compose up, Docker creates a user-defined bridge network for your project. Think of a bridge network as a virtual switch inside your host machine. Any container attached to this network can communicate with any other container on the same network using their service names.

Because these networks are isolated, containers from one project cannot "see" or ping containers from another project unless you explicitly configure them to share a network. This is a crucial security feature: by default, your production database container is unreachable by a rogue container you might be running for an experiment.

How Internal DNS Works

You don't need to hardcode IP addresses (which change every time a container restarts). Instead, Docker provides an internal DNS server. Every service defined in your docker-compose.yml is automatically registered in this DNS.

If you have a service named db, any other container in the same network can reach it simply by using the hostname db. Docker’s internal resolver intercepts this request and translates it to the correct private IP address within the bridge network.

Worked Example: Ping Between Containers

Night view of an illuminated shipping port with cranes and containers, reflecting industrial activity.

Let's verify this behavior. Suppose we have a simple docker-compose.yml file:

YAML
services:
  web:
    image: alpine
    command: sleep infinity
  db:
    image: alpine
    command: sleep infinity

When you run docker compose up -d, Docker starts both containers on the same network. We can now use docker compose exec to enter the web container and ping the db service.

  1. Start the services: docker compose up -d

  2. Test internal communication: docker compose exec web ping -c 3 db

You will see output indicating that the web container successfully reached db and received responses. The ping command resolved db to an internal IP address (usually starting with 172.x.x.x) automatically.

Hands-on Exercise

  1. Add a third service called cache to your existing Compose file using the alpine image.
  2. Bring the stack up.
  3. From the web container, run a ping to the cache service.
  4. Verify that you can also ping the web service from the cache container.

This confirms that your network is fully meshed, allowing bidirectional communication between all services in the stack.

Common Pitfalls

  • Relying on IP Addresses: Never use IP addresses in your application code. If a container is recreated, its IP will likely change. Always use the service name as the hostname.
  • External vs. Internal Networks: Remember that localhost inside a container refers to the container itself, not your host machine. If you need to reach a service running directly on your host, use host.docker.internal (on Docker Desktop).
  • Forgetting to Link Networks: If you manually define multiple networks in Compose, a container must be added to the same network as its target to communicate with it.

FAQ

Q: Can I reach a container from outside the Docker network? A: Only if you map ports using the ports directive. Otherwise, the network remains private to the host.

Q: Does internal DNS work if I don't use Docker Compose? A: It works if you use a user-defined bridge network created with docker network create. It does not work on the default bridge network that Docker creates when you run raw docker run commands.

Recap

Docker simplifies complex infrastructure by providing isolated bridge networks and an automated internal DNS. By using service names as hostnames, your application components can discover and communicate with each other reliably, regardless of their underlying IP addresses. This isolation keeps your services secure by default while providing a robust environment for multi-service applications.

Up next: We will secure our database credentials and API keys by Managing Secret Configuration using environment files.

Similar Posts