Docker
04 / 05

Docker Compose & Networking

Docker Compose & Networking

docker-compose.yml Structure

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
      target: runner         # multi-stage target
      args:
        BUILD_VERSION: "1.0"
    image: myapp:latest
    container_name: myapp
    restart: unless-stopped  # no | always | on-failure | unless-stopped
    ports:
      - "3000:3000"          # host:container
    environment:
      NODE_ENV: production
      DATABASE_URL: postgres://user:pass@db:5432/mydb
    env_file:
      - .env.production
    volumes:
      - ./uploads:/app/uploads       # bind mount
      - app_data:/app/data           # named volume
    networks:
      - app_net
    depends_on:
      db:
        condition: service_healthy   # wait for healthcheck
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 15s
    deploy:
      resources:
        limits:
          cpus: "0.5"
          memory: 512M

  db:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: mydb
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
    volumes:
      - pg_data:/var/lib/postgresql/data
      - ./db/init.sql:/docker-entrypoint-initdb.d/init.sql
    networks:
      - app_net
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user -d mydb"]
      interval: 5s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    command: redis-server --requirepass secretpassword --appendonly yes
    volumes:
      - redis_data:/data
    networks:
      - app_net

  nginx:
    image: nginx:1.25-alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./certbot/conf:/etc/letsencrypt:ro
    depends_on:
      - app
    networks:
      - app_net

volumes:
  pg_data:
  redis_data:
  app_data:

networks:
  app_net:
    driver: bridge

Compose Commands

# Start / stop
docker compose up -d                   # start all services detached
docker compose up -d app db            # start specific services
docker compose down                    # stop and remove containers
docker compose down -v                 # also remove volumes
docker compose stop                    # stop without removing
docker compose start                   # start stopped containers
docker compose restart app             # restart specific service

# Build
docker compose build                   # build all images
docker compose build app               # build specific service
docker compose build --no-cache app    # ignore cache

# Logs
docker compose logs                    # all logs
docker compose logs -f app             # follow app logs
docker compose logs --tail 50 db       # last 50 lines

# Scale
docker compose up -d --scale app=3    # run 3 app containers

# Exec
docker compose exec app bash           # shell into service
docker compose exec db psql -U user mydb

# Run one-off command
docker compose run --rm app node migrate.js

# Status
docker compose ps                      # service status
docker compose top                     # processes in services

# Config
docker compose config                  # validate + show merged config

Networking

  • Bridge (default) — isolated network, containers communicate by service name as DNS

  • Host — container shares host network stack (Linux only, fastest)

  • None — completely isolated, no networking

  • Overlay — multi-host (Docker Swarm / Kubernetes)

# Service discovery in Compose — use service name as hostname
# From 'app' container, connect to db: postgres://user:pass@db:5432/mydb
# From 'app' container, connect to redis: redis://redis:6379

# Network commands
docker network ls
docker network inspect app_app_net
docker network create mynet
docker network connect mynet container1
docker network disconnect mynet container1

Override Files

# docker-compose.override.yml is merged automatically in dev
# Use for dev-specific settings (volume mounts, debug ports)

# Explicitly specify files:
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

# Common pattern:
# docker-compose.yml          — base config
# docker-compose.override.yml — dev overrides (auto-loaded)
# docker-compose.prod.yml     — prod overrides (explicit)

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free