Isaac.

Docker Compose Orchestration

Orchestrate multi-container applications with Docker Compose.

By EMEPublished: February 20, 2025
docker composeorchestrationcontainersmicroservices

A Simple Analogy

Docker Compose is like a conductor coordinating an orchestra. Each service is an instrument, Compose ensures they start together, communicate, and scale in harmony.


Why Docker Compose?

  • Single command: Start entire stack with docker-compose up
  • Local development: Full environment locally
  • Service networking: Containers communicate automatically
  • Volume management: Persist data across restarts
  • Environment configuration: Manage multiple environments

Basic Compose File

version: '3.8'

services:
  web:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html
    depends_on:
      - api

  api:
    build:
      context: ./api
      dockerfile: Dockerfile
    environment:
      - DATABASE_URL=postgresql://user:pass@db:5432/myapp
      - LOG_LEVEL=debug
    ports:
      - "3000:3000"
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres:15
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: myapp
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  postgres_data:

networks:
  default:
    name: myapp-network

Common Commands

# Start all services
docker-compose up -d

# View logs
docker-compose logs -f api

# Stop services
docker-compose down

# Remove volumes too
docker-compose down -v

# Restart service
docker-compose restart api

# Scale service
docker-compose up -d --scale worker=3

# Execute command in container
docker-compose exec api dotnet ef database update

# Rebuild images
docker-compose build --no-cache

Environment Configuration

version: '3.8'

services:
  app:
    image: myapp:latest
    environment:
      - NODE_ENV=production
      - DATABASE_URL=${DATABASE_URL}
      - API_KEY=${API_KEY}
    env_file:
      - .env
      - .env.production

  db:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password

secrets:
  db_password:
    file: ./db_password.txt

Multi-Environment Setup

# .env.development
DATABASE_URL=postgresql://user:pass@db:5432/dev
DEBUG=true

# .env.production
DATABASE_URL=postgresql://user:secure@prod-db:5432/live
DEBUG=false
# Start development environment
docker-compose --env-file .env.development up

# Start production environment
docker-compose --env-file .env.production up

Override Compose Files

# Base configuration
# docker-compose.yml

# Development overrides
# docker-compose.dev.yml
version: '3.8'
services:
  api:
    build:
      context: ./api
      dockerfile: Dockerfile.dev
    volumes:
      - ./api:/app  # Hot reload
    environment:
      - DEBUG=true

# Run with overrides
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up

Practical Example

version: '3.8'

services:
  frontend:
    build: ./web
    ports:
      - "3000:3000"
    environment:
      - REACT_APP_API_URL=http://api:3001

  api:
    build: ./api
    ports:
      - "3001:3001"
    environment:
      - DATABASE_URL=mongodb://mongo:27017/myapp
    depends_on:
      mongo:
        condition: service_healthy

  mongo:
    image: mongo:latest
    volumes:
      - mongo_data:/data/db
    healthcheck:
      test: echo 'db.runCommand("ping").ok' | mongosh localhost:27017/test
      interval: 10s

  redis:
    image: redis:latest
    ports:
      - "6379:6379"

volumes:
  mongo_data:

Best Practices

  1. Use health checks: Ensure services are ready
  2. Set dependencies: Start in correct order
  3. Manage volumes: Persist important data
  4. Network isolation: Services communicate via network
  5. Environment files: Don't commit secrets

Related Concepts

  • Kubernetes for production orchestration
  • Docker networking and DNS
  • Volume drivers (local, named)
  • Service discovery

Summary

Docker Compose simplifies development of multi-service applications. Use it to define entire stacks locally before deploying to Kubernetes or cloud platforms.