Networking in Compose

[!NOTE] This module explores the core principles of Networking in Compose, deriving solutions from first principles and hardware constraints to build world-class, production-ready expertise.

1. The Magic of Service Discovery

When you run docker run, you often have to deal with IP addresses or messy --link flags.

In Compose, networking is automatic.

The Rule: Every service can reach every other service by its service name.

If you have a service named db, your API can connect to it using the hostname db.


2. How it Works: The Default Network

When you run docker compose up:

  1. Docker creates a new bridge network (e.g., myapp_default).
  2. It attaches all containers to this network.
  3. It adds an entry to its Internal DNS for each service.

Interactive: DNS Simulator

Type a hostname to see how Docker resolves it.

Container: api
root@api:/# ping
Internal DNS Resolver
Waiting for query...
api 172.20.0.2
db 172.20.0.3
redis 172.20.0.4

[!WARNING] Don’t use localhost Inside a container, localhost refers to the container itself, not your laptop or other containers. Always use the service name.


3. Custom Networks & Security

By default, all services are on one big shared network. For production, you often want to isolate them.

Goal: The frontend should talk to backend, but frontend should NOT be able to talk to db directly.

services:
  proxy:
    image: nginx
    networks:
      - frontend-net

  app:
    image: my-app
    networks:
      - frontend-net
      - backend-net

  db:
    image: postgres
    networks:
      - backend-net

networks:
  frontend-net:
  backend-net:

Network Drivers

  1. Bridge (Default): Standard isolated network.
  2. Host: Removes network isolation. The container shares the host’s networking stack.
    • Performance: Highest (no NAT).
    • Security: Low.
    • Usage: network_mode: host
  3. None: No networking.

4. Network Aliases

You can give a service multiple names on a specific network.

services:
  db:
    image: postgres
    networks:
      default:
        aliases:
          - database
          - pg-primary

Now ping db, ping database, and ping pg-primary all resolve to the same container. This is useful for blue-green deployments or migrating legacy code.