导航菜单

07 - Docker Compose

Docker Compose

In previous tutorials, we learned how to create and manage a single container with Docker. In real-world scenarios, we usually need to run multiple related containers to build a complete application. For example, a web app might include a web server, database, and cache. Manually managing these containers is tedious and error-prone—this is where Docker Compose helps.

What is Docker Compose?

Docker Compose is a tool for defining and running multi-container Docker applications. With Compose, you configure your app’s services in a YAML file, then start everything with a single command.

Install Docker Compose

On Windows and macOS

If you installed Docker Desktop (Windows or macOS), Docker Compose is included—no extra installation needed.

On Linux

# Download Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.18.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# Add execute permission
sudo chmod +x /usr/local/bin/docker-compose

# Verify installation
docker-compose --version

Docker Compose key concepts

docker-compose.yml

Docker Compose uses a YAML file (commonly docker-compose.yml) to define services, networks, and volumes. A simple example:

version: '3'

services:
  web:
    image: nginx:latest
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html
      
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: example
      MYSQL_DATABASE: myapp
    volumes:
      - db-data:/var/lib/mysql

volumes:
  db-data:

Services

Services are the building blocks of your app—typically one container per service. A service can be created from an image or built via a Dockerfile.

Networks

Compose creates a default network so services can talk to each other by service name. You can also customize network settings.

Volumes

Volumes are used to persist data or share data between services.

Common Docker Compose commands

Start services

# Run in the directory containing docker-compose.yml
docker-compose up

# Run in the background
docker-compose up -d

Stop services

docker-compose down

# Remove volumes as well
docker-compose down -v

View service status

docker-compose ps

View service logs

docker-compose logs

# Logs for a specific service
docker-compose logs web

# Tail logs
docker-compose logs -f

Run commands

# Execute a command inside a service container
docker-compose exec web bash

Build services

# Build or rebuild services
docker-compose build

# Build and start services
docker-compose up --build

docker-compose.yml explained

version

Specifies the Compose file format version.

version: '3'

services

Defines the services in your application.

services:
  web:
    image: nginx:latest
    # more config...
  db:
    image: postgres:13
    # more config...

Common service options

image

Specify the image to use.

image: redis:6

build

Build an image from a Dockerfile.

build:
  context: ./dir  # build context path
  dockerfile: Dockerfile.dev  # optional, specify Dockerfile

ports

Expose ports.

ports:
  - "3000:3000"  # host:container

volumes

Mount volumes or bind mounts.

volumes:
  - ./data:/app/data  # bind mount
  - logs:/app/logs    # named volume

environment

Set environment variables.

environment:
  NODE_ENV: production
  API_KEY: secret

depends_on

Define service dependencies.

depends_on:
  - db
  - redis

networks

Specify networks a service connects to.

networks:
  - frontend
  - backend

restart

Set the container restart policy.

restart: always  # options: no, always, on-failure, unless-stopped

networks

Define networks used by the app.

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge

volumes

Define volumes used by the app.

volumes:
  db-data:
  logs:

Practical examples

Web app + database + Redis cache

version: '3'

services:
  web:
    build: ./app
    ports:
      - "3000:3000"
    depends_on:
      - db
      - redis
    environment:
      - NODE_ENV=production
      - DB_HOST=db
      - REDIS_HOST=redis
    networks:
      - app-network

  db:
    image: postgres:13
    environment:
      - POSTGRES_USER=myuser
      - POSTGRES_PASSWORD=mypassword
      - POSTGRES_DB=myapp
    volumes:
      - db-data:/var/lib/postgresql/data
    networks:
      - app-network

  redis:
    image: redis:6
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

volumes:
  db-data:

WordPress + MySQL

version: '3'

services:
  wordpress:
    image: wordpress:latest
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - wordpress:/var/www/html
    depends_on:
      - db

  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
    volumes:
      - db:/var/lib/mysql

volumes:
  wordpress:
  db:

Best practices for Docker Compose

  1. Use environment variables: Put secrets and environment-specific configs in a .env file rather than hard-coding them in docker-compose.yml.

  2. Organize services logically: Group related services and define proper dependencies.

  3. Use version control: Track docker-compose.yml in version control, but exclude .env.

  4. Add health checks: Add health checks to ensure services are healthy.

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost"]
  interval: 1m
  timeout: 10s
  retries: 3
  1. Use named volumes: Prefer named volumes for persistent data instead of anonymous volumes.

Summary

Docker Compose greatly simplifies managing multi-container applications. With a single YAML file you can define services, networks, and volumes, then start and manage the entire stack with simple commands. This boosts developer productivity and keeps dev, test, and production environments consistent. In the next tutorial, we’ll cover Docker production best practices including security, monitoring, and performance tuning.

搜索