What is Docker Compose?

Docker Compose is a tool for defining and running multi-container Docker applications using YAML configuration files.

Why Use Docker Compose?

  • Declarative Configuration: Define infrastructure as code
  • Multi-Container Management: Orchestrate related services
  • Environment Consistency: Reproducible deployments
  • Simplified Commands: Single command deployment
  • Network Management: Automatic service networking

Docker Compose File Structure

Basic YAML structure:

version: "3.8"

services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html
    
  database:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: secret
    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data:

networks:
  default:
    driver: bridge

MCT Services Compose Structure

Our multi-service architecture:

version: "3.8"

services:
  traefik:
    image: traefik:v2.10
    container_name: traefik
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik:/etc/traefik
    labels:
      - "traefik.enable=true"

  nextcloud:
    image: nextcloud:apache
    container_name: nextcloud
    restart: unless-stopped
    volumes:
      - nextcloud_data:/var/www/html
      - ./nextcloud/config:/var/www/html/config
    environment:
      - MYSQL_HOST=mariadb
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_PASSWORD=secure_password
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nextcloud.rule=Host(`nextcloud.mct.local`)"
    depends_on:
      - mariadb

  mariadb:
    image: mariadb:10.11
    container_name: mariadb
    restart: unless-stopped
    environment:
      - MYSQL_ROOT_PASSWORD=root_password
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_PASSWORD=secure_password
    volumes:
      - mariadb_data:/var/lib/mysql

volumes:
  nextcloud_data:
  mariadb_data:

networks:
  default:
    name: mct_network

Essential Compose Commands

# Start all services
docker-compose up -d

# View running services
docker-compose ps

# View logs
docker-compose logs
docker-compose logs nextcloud

# Stop services
docker-compose stop

# Stop and remove containers
docker-compose down

# Rebuild and restart
docker-compose up -d --build

# Scale services
docker-compose up -d --scale web=3

Service Configuration Options

Image and Build

services:
  app:
    # Use existing image
    image: nginx:alpine
    
    # Or build from Dockerfile
    build:
      context: ./app
      dockerfile: Dockerfile

Environment Variables

services:
  app:
    environment:
      - DEBUG=true
      - DATABASE_URL=mysql://user:pass@db/mydb
    
    # Or use env file
    env_file:
      - .env

Volume Mounting

services:
  app:
    volumes:
      # Named volume
      - app_data:/app/data
      
      # Bind mount
      - ./config:/app/config
      
      # Read-only mount
      - ./static:/app/static:ro

Network Configuration

services:
  app:
    networks:
      - frontend
      - backend
    
networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true

Dependency Management

Control service startup order:

services:
  web:
    depends_on:
      - database
      - redis
    
  database:
    image: mysql:8.0
    
  redis:
    image: redis:alpine

Health Checks

Monitor service health:

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

Environment-Specific Configurations

Use multiple compose files:

# docker-compose.yml (base)
# docker-compose.override.yml (development)
# docker-compose.prod.yml (production)

# Deploy production
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

Best Practices

  • Version Control: Store compose files in git
  • Environment Files: Use .env for sensitive data
  • Named Volumes: Prefer named volumes over bind mounts
  • Resource Limits: Set memory and CPU limits
  • Restart Policies: Configure appropriate restart behavior

Troubleshooting

# Check service status
docker-compose ps

# View all logs
docker-compose logs

# Follow logs in real-time
docker-compose logs -f

# Restart specific service
docker-compose restart nextcloud

# Rebuild service
docker-compose up -d --no-deps --build nextcloud

Practical Exercise

Task: Create a multi-service application

  1. Design a simple web application stack
  2. Write Docker Compose configuration
  3. Include web server, database, and cache
  4. Configure service dependencies
  5. Add health checks and restart policies
  6. Test deployment and scaling
  7. Practice troubleshooting scenarios
Last modified: Thursday, 6 November 2025, 8:49 AM