Claude
Skills
Sign in
Back

docker-compose-networking

Included with Lifetime
$97 forever

Use when configuring networks and service communication in Docker Compose including bridge networks, overlay networks, service discovery, and inter-service communication.

Cloud & DevOps

What this skill does


# Docker Compose Networking

Master network configuration and service communication patterns in Docker Compose for building secure, scalable multi-container applications.

## Default Bridge Network

Docker Compose automatically creates a default bridge network for all services in a compose file:

```yaml
version: '3.8'

services:
  frontend:
    image: nginx:alpine
    ports:
      - "80:80"
    # Can reach backend using service name as hostname

  backend:
    image: node:18-alpine
    command: node server.js
    # Accessible at hostname 'backend' from frontend

  database:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: secret
    # Accessible at hostname 'database' from backend
```

In this setup:

- All services can communicate using service names as hostnames
- Frontend can reach backend at `http://backend:3000`
- Backend can reach database at `postgres://database:5432`
- Only frontend's port 80 is exposed to host

## Custom Bridge Networks

Define custom networks for service isolation and segmentation:

```yaml
version: '3.8'

services:
  frontend:
    image: nginx:alpine
    networks:
      - frontend-network
    ports:
      - "80:80"

  api:
    image: node:18-alpine
    networks:
      - frontend-network
      - backend-network
    environment:
      DATABASE_URL: postgresql://db:5432/app

  database:
    image: postgres:15-alpine
    networks:
      - backend-network
    environment:
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: app
    volumes:
      - db-data:/var/lib/postgresql/data

  cache:
    image: redis:7-alpine
    networks:
      - backend-network
    command: redis-server --appendonly yes
    volumes:
      - redis-data:/data

networks:
  frontend-network:
    driver: bridge
  backend-network:
    driver: bridge
    internal: true

volumes:
  db-data:
  redis-data:
```

Network isolation:

- Frontend can only reach API
- Frontend cannot reach database or cache directly
- API can reach all services
- Backend network is internal (no external access)

## Network Aliases

Configure multiple hostnames for service discovery:

```yaml
version: '3.8'

services:
  web:
    image: nginx:alpine
    networks:
      public:
        aliases:
          - website
          - www
          - web-server
      internal:
        aliases:
          - web-internal

  api:
    image: node:18-alpine
    networks:
      public:
        aliases:
          - api-server
          - backend
      internal:
        aliases:
          - api-internal
    depends_on:
      - database

  database:
    image: postgres:15-alpine
    networks:
      internal:
        aliases:
          - db
          - postgres
          - primary-db
    environment:
      POSTGRES_PASSWORD: secret

networks:
  public:
    driver: bridge
  internal:
    driver: bridge
    internal: true
```

Services can be reached by any of their aliases:

- `http://website`, `http://www`, `http://web-server` all reach web service
- `postgresql://db:5432`, `postgresql://postgres:5432` both reach database

## Static IP Addresses

Assign fixed IP addresses for services requiring stable networking:

```yaml
version: '3.8'

services:
  loadbalancer:
    image: nginx:alpine
    networks:
      app-network:
        ipv4_address: 172.28.1.10
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro

  app-1:
    image: myapp:latest
    networks:
      app-network:
        ipv4_address: 172.28.1.11
    environment:
      APP_ID: "1"

  app-2:
    image: myapp:latest
    networks:
      app-network:
        ipv4_address: 172.28.1.12
    environment:
      APP_ID: "2"

  app-3:
    image: myapp:latest
    networks:
      app-network:
        ipv4_address: 172.28.1.13
    environment:
      APP_ID: "3"

  database:
    image: postgres:15-alpine
    networks:
      app-network:
        ipv4_address: 172.28.1.20
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - pgdata:/var/lib/postgresql/data

networks:
  app-network:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.28.0.0/16
          gateway: 172.28.1.1

volumes:
  pgdata:
```

## External Networks

Connect to existing Docker networks created outside Compose:

```yaml
version: '3.8'

services:
  api:
    image: node:18-alpine
    networks:
      - app-network
      - shared-network
    environment:
      DATABASE_URL: postgresql://db:5432/app

  database:
    image: postgres:15-alpine
    networks:
      - app-network
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - pgdata:/var/lib/postgresql/data

networks:
  app-network:
    driver: bridge

  shared-network:
    external: true
    name: company-shared-network

volumes:
  pgdata:
```

Create external network first:

```bash
docker network create company-shared-network
docker compose up -d
```

## Host Network Mode

Use host networking for maximum performance (Linux only):

```yaml
version: '3.8'

services:
  high-performance-app:
    image: myapp:latest
    network_mode: "host"
    environment:
      BIND_ADDRESS: "0.0.0.0"
      PORT: "8080"
    # No port mapping needed - directly uses host's network stack

  monitoring:
    image: prometheus:latest
    network_mode: "host"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus-data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.listen-address=0.0.0.0:9090'

volumes:
  prometheus-data:
```

Note: Host networking bypasses Docker network isolation and is typically used for monitoring tools or high-throughput applications.

## Service Discovery and DNS

Configure DNS resolution and service discovery:

```yaml
version: '3.8'

services:
  api:
    image: node:18-alpine
    networks:
      - app-network
    dns:
      - 8.8.8.8
      - 8.8.4.4
    dns_search:
      - company.local
    extra_hosts:
      - "legacy-api.company.local:192.168.1.100"
      - "auth-service.company.local:192.168.1.101"
    environment:
      DATABASE_HOST: database.company.local

  database:
    image: postgres:15-alpine
    networks:
      app-network:
        aliases:
          - database.company.local
          - db.company.local
    hostname: primary-database
    domainname: company.local
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - pgdata:/var/lib/postgresql/data

networks:
  app-network:
    driver: bridge
    driver_opts:
      com.docker.network.bridge.name: br-company-app

volumes:
  pgdata:
```

## Link Containers (Legacy)

While `links` is deprecated, understanding it helps migrate legacy configurations:

```yaml
version: '3.8'

services:
  # Modern approach - use networks instead
  web:
    image: nginx:alpine
    networks:
      - app-network
    depends_on:
      - api

  api:
    image: node:18-alpine
    networks:
      - app-network
    depends_on:
      - database
    environment:
      # Use service name as hostname
      DATABASE_URL: postgresql://database:5432/app

  database:
    image: postgres:15-alpine
    networks:
      - app-network
    environment:
      POSTGRES_PASSWORD: secret

networks:
  app-network:
    driver: bridge
```

## Multi-Network Architecture

Complex applications with multiple isolated networks:

```yaml
version: '3.8'

services:
  nginx:
    image: nginx:alpine
    networks:
      - public
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./ssl:/etc/nginx/ssl:ro
    depends_on:
      - frontend
      - api

  frontend:
    image: react-app:latest
    networks:
      - public
      - frontend-tier
    environment:
      API_URL: http://api:3000

  api:
    image: node-api:latest
    networks:
      - frontend-tier
      - backend-tier
    environment:
      DATABASE_URL: postgresql://postgres:5432/app
      REDIS_URL: redis://cache:6379
      QUEUE_URL: amqp://rabbitmq:5672
    depends_on:
    

Related in Cloud & DevOps