Isaac.

Docker Compose Complete Guide

Formatted for a dark-theme React/TSX page. All content preserved and properly escaped for JSX.

What is Docker Compose?

Docker Compose is a tool for defining and running multi-container Docker applications. It uses a YAML file to configure your application's services, networks, and volumes, then creates and starts all the services with a single command.

Key Concepts

1. docker-compose.yml

The configuration file that defines services, networks, and volumes for your application.

2. Services

Individual containers that make up your application (web server, database, cache, etc.).

3. Projects

A set of services that work together, identified by a project name.

Installation

Docker Compose is included with:

  • Docker Desktop (Windows/Mac)
  • On Linux: sudo apt-get install docker-compose-plugin

Verify installation:

docker compose version

Basic Structure

Minimal docker-compose.yml:

version: '3.8'
services:
  web:
    image: nginx:latest
    ports:
      - "80:80"

Example (highlighted): Minimal docker-compose.yml

version: '3.8'
services:
  web:
    image: nginx:latest
    ports:
      - "80:80"

Core Components

1. Services Configuration

services:
  webapp:
    image: myapp:latest
    build: .
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql://user:pass@db:5432/mydb
    depends_on:
      - db
    volumes:
      - ./app:/code
    networks:
      - app-network

  db:
    image: postgres:13
    environment:
      POSTGRES_DB: mydb
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
    volumes:
      - db_data:/var/lib/postgresql/data
    networks:
      - app-network

  redis:
    image: redis:alpine
    networks:
      - app-network

2. Networks

networks:
  app-network:
    driver: bridge
    driver_opts:
      com.docker.network.driver.mtu: 1450

3. Volumes

volumes:
  db_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ./postgres-data

4. Secrets (for sensitive data)

secrets:
  db_password:
    file: ./secrets/db_password.txt

services:
  db:
    image: postgres
    secrets:
      - db_password

Essential Commands

Basic Operations

# Start services in foreground
docker compose up

# Start in background
docker compose up -d

# Stop services
docker compose down

# View running services
docker compose ps

# View logs
docker compose logs
docker compose logs -f  # Follow logs
docker compose logs service_name  # Specific service

# Build images
docker compose build

# Pull images
docker compose pull

Management Commands

# Execute command in running container
docker compose exec service_name command

# Scale services
docker compose up --scale web=3 --scale worker=2

# Restart services
docker compose restart

# Pause/unpause
docker compose pause
docker compose unpause

# Remove containers and volumes
docker compose down -v

# View resource usage
docker compose top

Advanced Configuration

1. Build Context with Dockerfile

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile.dev
      args:
        BUILD_ENV: production
    image: myapp:custom

2. Environment Variables

services:
  web:
    image: nginx
    environment:
      - NGINX_HOST=localhost
      - NGINX_PORT=80
    env_file:
      - .env
      - .env.production

3. Health Checks

services:
  web:
    image: nginx
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

4. Resource Limits

services:
  web:
    image: nginx
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: '0.50'
        reservations:
          memory: 256M
          cpus: '0.25'

5. Dependencies and Startup Order

services:
  web:
    image: nginx
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started

  db:
    image: postgres
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5

Real-World Examples

1. WordPress with MySQL

version: '3.8'
services:
  db:
    image: mysql:8.0
    volumes:
      - db_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpresspass

  wordpress:
    image: wordpress:latest
    ports:
      - "8000:80"
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpresspass
    depends_on:
      - db

volumes:
  db_data:

2. Full-Stack Application

version: '3.8'

services:
  frontend:
    build: ./frontend
    ports:
      - "3000:3000"
    volumes:
      - ./frontend:/app
      - /app/node_modules
    environment:
      - REACT_APP_API_URL=http://localhost:8000/api

  backend:
    build: ./backend
    ports:
      - "8000:8000"
    volumes:
      - ./backend:/app
    environment:
      - DATABASE_URL=postgresql://user:pass@db:5432/app
      - REDIS_URL=redis://redis:6379
    depends_on:
      - db
      - redis

  db:
    image: postgres:13
    environment:
      POSTGRES_DB: app
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
    volumes:
      - postgres_data:/var/lib/postgresql/data

  redis:
    image: redis:alpine
    volumes:
      - redis_data:/data

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - frontend
      - backend

volumes:
  postgres_data:
  redis_data:

Development vs Production

Development Configuration

# docker-compose.dev.yml
version: '3.8'

services:
  web:
    build: .
    ports:
      - "8000:8000"
    volumes:
      - .:/code
    environment:
      - DEBUG=true
    command: python manage.py runserver 0.0.0.0:8000

Production Configuration

# docker-compose.prod.yml
version: '3.8'

services:
  web:
    image: myapp:prod
    ports:
      - "80:8000"
    environment:
      - DEBUG=false
    restart: unless-stopped
    deploy:
      replicas: 3

Useful Features

1. Multiple Compose Files

# Override base configuration
docker compose -f docker-compose.yml -f docker-compose.prod.yml up

2. Profiles

services:
  web:
    # ... normal config
  
  dev-tools:
    profiles: ["dev"]
    image: dev-tools:latest
    # ... development tools config

3. Extensions and Reuse

# Use extension fields for reusable configurations
x-logging: &default-logging
  options:
    max-size: "10m"
    max-file: "3"

services:
  web:
    image: nginx
    logging: *default-logging

Best Practices

1. Security

services:
  db:
    image: postgres
    # Don't run as root
    user: postgres
    # Read-only root filesystem where possible
    read_only: true

2. Efficiency

services:
  app:
    build:
      context: .
      # Use .dockerignore to exclude unnecessary files
    # Share common base images

3. Organization

# Use meaningful service names
services:
  database:  # instead of 'db'
    image: postgres
  cache:
    image: redis
  application:
    build: .

Troubleshooting Commands

# Check configuration
docker compose config

# See what would be created
docker compose up --dry-run

# Force rebuild
docker compose build --no-cache

# Remove all containers and images
docker compose down --rmi all

# Follow specific service logs
docker compose logs -f service_name

Common Patterns

1. Service Discovery
Services can communicate using service names as hostnames.

2. Development Hot-Reload
Mount source code as volumes for live reloading.

3. Database Migrations

services:
  migrations:
    build: .
    command: python manage.py migrate
    depends_on:
      db:
        condition: service_healthy

Next Steps

  1. Practice with simple multi-container applications
  2. Explore Docker Compose for different stacks (LAMP, MEAN, etc.)
  3. Learn about Docker Swarm for orchestration
  4. Study production deployment strategies

This covers the essential knowledge you need to work effectively with Docker Compose. Start with simple configurations and gradually incorporate more advanced features as needed!