Docker Compose

DevOpscontainersDockermulti-containerorchestrationdevelopment environmentYAML

DevOps Tool

Docker Compose

Overview

Docker Compose is a tool that simplifies the definition and execution of multi-container Docker applications. It allows you to define multiple services using YAML configuration files and manage them with single commands.

Details

Docker Compose is an orchestration tool for managing multi-container Docker applications declaratively. Originally developed as the Fig project by Fig Inc. in 2014, it was acquired by Docker and evolved into its current form. By describing service definitions, networks, volumes, and more in a docker-compose.yml file, complex multi-container environments can be built with a single docker-compose up command. It's widely used as an essential tool for development environments and local testing, efficiently managing interconnected systems like web applications, databases, queue systems, and caches. Significant improvements in v2 include enhanced performance, profile features for environment-specific management, GPU support, and Watch functionality. Unlike Kubernetes, it's specialized for container management on a single host and can integrate with Docker Swarm. Currently, it's a standard tool for development teams, with expanding use in local development environment setup, CI/CD pipelines, and small-scale production environments.

Advantages and Disadvantages

Advantages

  • Simple configuration: Intuitive YAML format configuration files
  • Single command execution: Start complex environments with one command
  • Development optimization: High productivity in local development
  • Environment reproducibility: Consistent development environments across teams
  • Inter-service connectivity: Automatic network configuration and service discovery
  • Profile features: Easy management of environment-specific configurations
  • Hot reload: Development efficiency through Watch functionality
  • Resource management: CPU/memory limits and health check support

Disadvantages

  • Single host limitation: Cannot scale across multiple servers
  • Production constraints: No high availability or auto-recovery features
  • Limited orchestration: Not as advanced as Kubernetes features
  • Persistent data: Volume management requires careful attention
  • Performance: Scalability limitations in large-scale environments
  • Network complexity: Difficult to configure advanced networking
  • Monitoring: Requires separate tools for full monitoring and log aggregation
  • Version management: Service dependency and update coordination challenges

Key Links

Code Examples

Basic Web Application

# docker-compose.yml
version: '3.8'

services:
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=development
      - DATABASE_URL=postgresql://user:password@db:5432/myapp
    depends_on:
      - db
      - redis
    volumes:
      - .:/app
      - node_modules:/app/node_modules

  db:
    image: postgres:15
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data

volumes:
  postgres_data:
  redis_data:
  node_modules:

WordPress + MySQL Environment

# wordpress-compose.yml
version: '3.8'

services:
  wordpress:
    image: wordpress:latest
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress_password
      WORDPRESS_DB_NAME: wordpress_db
    volumes:
      - wordpress_data:/var/www/html
    depends_on:
      mysql:
        condition: service_healthy

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_DATABASE: wordpress_db
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress_password
      MYSQL_ROOT_PASSWORD: root_password
    volumes:
      - mysql_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 30s
      timeout: 10s
      retries: 3

volumes:
  wordpress_data:
  mysql_data:

Microservices Architecture

# microservices-compose.yml
version: '3.8'

services:
  api-gateway:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - user-service
      - order-service
      - product-service

  user-service:
    build: ./services/user
    environment:
      - DATABASE_URL=postgresql://user:pass@user-db:5432/users
    depends_on:
      - user-db

  order-service:
    build: ./services/order
    environment:
      - DATABASE_URL=postgresql://order:pass@order-db:5432/orders
      - REDIS_URL=redis://redis:6379
    depends_on:
      - order-db
      - redis

  product-service:
    build: ./services/product
    environment:
      - DATABASE_URL=mongodb://product-db:27017/products

  user-db:
    image: postgres:15
    environment:
      POSTGRES_DB: users
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass

  order-db:
    image: postgres:15
    environment:
      POSTGRES_DB: orders
      POSTGRES_USER: order
      POSTGRES_PASSWORD: pass

  product-db:
    image: mongo:6

  redis:
    image: redis:7-alpine

Development Environment with Profiles

# docker-compose.yml
version: '3.8'

services:
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=development
    volumes:
      - .:/app
    profiles:
      - development

  web-prod:
    build:
      context: .
      target: production
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
    profiles:
      - production

  db:
    image: postgres:15
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password

  test-runner:
    build: .
    command: npm test
    environment:
      - NODE_ENV=test
    profiles:
      - testing

Health Checks and Dependency Management

# health-check-compose.yml
version: '3.8'

services:
  web:
    build: .
    ports:
      - "3000:3000"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started

  db:
    image: postgres:15
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user -d myapp"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 3s
      retries: 3

Docker Compose CLI Commands

# Basic operations
docker-compose up                    # Start services (foreground)
docker-compose up -d                 # Start services (background)
docker-compose down                  # Stop and remove services
docker-compose down -v               # Remove volumes too

# Build and update
docker-compose build                 # Build images
docker-compose up --build            # Build then start
docker-compose pull                  # Update images

# Individual service operations
docker-compose up web                # Start specific service only
docker-compose restart web           # Restart service
docker-compose stop web              # Stop service

# Logs and monitoring
docker-compose logs                  # All service logs
docker-compose logs -f web           # Specific service logs (follow)
docker-compose ps                    # Check service status
docker-compose top                   # Check processes

# Execution and debugging
docker-compose exec web bash         # Execute command in service
docker-compose run --rm web npm test # One-time command execution

# Profile usage
docker-compose --profile development up
docker-compose --profile production up -d