Free — no signup required

Networking in Compose

2 min read

Automatic DNS — No IP Addresses Required

Networking is one of the most powerful and underappreciated features of Docker Compose. When you run docker-compose up, Compose automatically creates a dedicated virtual bridge network for your project (named <project-name>_default, where the project name defaults to the directory name). Every service defined in your file is attached to this network automatically.

More importantly, Compose configures internal DNS so that each service is reachable by its service name as a hostname. In the three-tier example above:

  • The web container connects to Postgres at db:5432 — not 172.18.0.3:5432.
  • The web container connects to Redis at redis:6379.
  • No IP addresses, no /etc/hosts editing, no --link flags.

This is why the DATABASE_URL in the example above uses @db:5432 — db is the service name, and Compose's DNS resolves it to the correct container IP automatically.

Custom Networks for Isolation

For more complex applications, you can define multiple networks to control which services can talk to each other. For example: a web service attached to both a frontend and a backend network, an api service attached only to backend, and a db service also attached only to backend.

In this setup, web is on both frontend and backend networks, so it can reach both api and db directly. Meanwhile, api and db are only on the backend network, so they cannot be reached from any service that is exclusively on the frontend network. If you added a dedicated reverse-proxy service attached only to frontend, it would be able to reach web but not api or db — that is the segmentation this pattern provides.

Interview Tip

A common interview question: "How does service discovery work in Docker Compose?" The answer: Compose creates a user-defined bridge network and registers each service name as a DNS entry within that network. Containers resolve service names to container IPs via Docker's embedded DNS server (running at 127.0.0.11 inside each container). This is fundamentally different from the deprecated --link flag, which injected /etc/hosts entries and had no dynamic update capability.

This is one of 18 chapters

Every chapter is free — Kubernetes, Terraform, SRE, distributed systems, and more — with fast daily review built in.

Sign up free