Skip to content

Chapter 4 of 8

Networking in Compose

Every Compose project gets a default network named <project>_default, and on that network services can resolve each other by service name. That name resolution is what makes the line depends_on: db actually useful: when your app says db:5432, it reaches the database container, not the host. This is also the most common stumbling block for newcomers, because inside a container, localhost refers to the container itself, not the host machine. To reach the host from a container, use the service name for other Compose services, or host.docker.internal on Docker Desktop. On Linux, host.docker.internal works too in recent versions, but the service name is always the cleanest answer.

You can declare additional networks under a top-level networks: key, specifying a driver like bridge and optionally IPAM configuration for static addressing. Services attach to networks via the service-level networks: key, which accepts a list, so a single service can be on multiple networks. This is the standard pattern for gateway or reverse-proxy containers that need to talk to both a public-facing frontend network and a private backend network while the app services themselves only sit on the backend. To join a network that was created outside this compose file, declare it with external: true; this is how you share a network across multiple Compose projects. For IPv6, set enable_ipv6: true on the network and provide a subnet under IPAM, and to pin a specific container to a fixed IP, set ipv4_address under the service's network entry.

For advanced topologies, you can use a different driver entirely. A macvlan network gives a container its own IP on the physical LAN, which is useful when a container needs to be reachable from other physical machines without NAT. To add DNS configuration that overrides container defaults, set the dns: key on a service with a list of resolvers, which is handy behind corporate DNS that can't resolve public hostnames. To add hostname aliases that resolve inside the container, use extra_hosts: for one-off mappings, or attach a service to a network with an aliases: list to give it additional hostnames visible to other services on that network. The expose: key differs from ports: in an important way: expose: only makes the port reachable to other services on the Compose network, while ports: publishes it to the host machine, with the syntax HOST:CONTAINER.

All chapters
  1. 1Compose File Anatomy
  2. 2Services, Dependencies, and Health
  3. 3Volumes, Mounts, and Data Persistence
  4. 4Networking in Compose
  5. 5Building, Scaling, and Resources
  6. 6Multi-Environment Compose and Configuration
  7. 7Logs, Debugging, and Common Gotchas
  8. 8Stack-Specific Recipes and Patterns

Drill it

Reading is not remembering. These come from the Docker Compose Recipes For Local Dev deck:

Q

Compose file directive to mount a host directory into a container?

volumes: - ./local:/app

Q

Restart a container automatically unless explicitly stopped?

restart: unless-stopped

Q

Define an environment variable in Compose?

environment:&lt;br&gt; - KEY=value or env_file: .env

Q

Wait for another service to be 'healthy' before starting?

depends_on:&lt;br&gt; db:&lt;br&gt; condition: service_healthy