Docker Compose 实战教程 — 多容器编排

适用人群:后端开发者、运维工程师
学习时长:约1-2天
重要程度:★★★★☆(生产部署必备)

一、Docker Compose是什么?

Docker Compose用于定义和运行多容器Docker应用,通过YAML文件配置所有服务。

特点说明
声明式配置YAML定义所有服务
一键启动docker-compose up
服务编排定义依赖关系
网络隔离自动创建网络

二、基础配置

2.1 基本语法

version: '3.8'

services:
  # Web应用
  web:
    build: .
    ports:
      - "8080:5000"
    environment:
      - DATABASE_URL=mysql://root:password@db:3306/mydb
    depends_on:
      - db
      - redis
    volumes:
      - ./uploads:/app/uploads
    restart: always

  # MySQL数据库
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: mydb
    ports:
      - "3306:3306"
    volumes:
      - mysql_data:/var/lib/mysql
    restart: always

  # Redis缓存
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    restart: always

volumes:
  mysql_data:
  redis_data:

2.2 常用命令

# 启动所有服务
docker-compose up -d

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs -f web

# 停止所有服务
docker-compose down

# 重建并启动
docker-compose up -d --build

# 进入容器
docker-compose exec web bash

# 查看资源使用
docker-compose top


三、完整项目配置

3.1 PHP + MySQL + Nginx

version: '3.8'

services:
  # PHP-FPM
  php:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./www:/var/www/html
    restart: always

  # Nginx
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./www:/var/www/html
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
      - ./ssl:/etc/nginx/ssl
    depends_on:
      - php
    restart: always

  # MySQL
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root123
      MYSQL_DATABASE: mydb
      MYSQL_USER: app
      MYSQL_PASSWORD: app123
    ports:
      - "3306:3306"
    volumes:
      - mysql_data:/var/lib/mysql
      - ./mysql/init.sql:/docker-entrypoint-initdb.d/init.sql
    restart: always

  # phpMyAdmin
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    ports:
      - "8080:80"
    environment:
      PMA_HOST: mysql
      PMA_USER: root
      PMA_PASSWORD: root123
    depends_on:
      - mysql
    restart: always

volumes:
  mysql_data:

# Dockerfile (PHP)
FROM php:8.2-fpm-alpine

RUN docker-php-ext-install pdo pdo_mysql mysqli

COPY . /var/www/html
WORKDIR /var/www/html

RUN chown -R www:www /var/www/html

# nginx/default.conf
server {
    listen 80;
    server_name localhost;
    root /var/www/html/public;
    index index.php index.html;
    
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    
    location ~ \.php$ {
        fastcgi_pass php:9000;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

3.2 Python + PostgreSQL + Redis

version: '3.8'

services:
  # Flask应用
  app:
    build: .
    ports:
      - "5000:5000"
    environment:
      - DATABASE_URL=postgresql://postgres:password@db:5432/mydb
      - REDIS_URL=redis://redis:6379/0
      - FLASK_ENV=production
    depends_on:
      - db
      - redis
    restart: always

  # PostgreSQL
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_PASSWORD: password
      POSTGRES_DB: mydb
    ports:
      - "5432:5432"
    volumes:
      - pg_data:/var/lib/postgresql/data
    restart: always

  # Redis
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    restart: always

  # Celery Worker(异步任务)
  celery:
    build: .
    command: celery -A app.celery worker --loglevel=info
    environment:
      - DATABASE_URL=postgresql://postgres:password@db:5432/mydb
      - REDIS_URL=redis://redis:6379/0
    depends_on:
      - db
      - redis
    restart: always

volumes:
  pg_data:
  redis_data:

3.3 Node.js + MongoDB + Redis

version: '3.8'

services:
  # Node.js应用
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - MONGODB_URI=mongodb://mongo:27017/mydb
      - REDIS_URL=redis://redis:6379
    depends_on:
      - mongo
      - redis
    restart: always

  # MongoDB
  mongo:
    image: mongo:7
    ports:
      - "27017:27017"
    volumes:
      - mongo_data:/data/db
    restart: always

  # Redis
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    restart: always

  # Nginx反向代理
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - app
    restart: always

volumes:
  mongo_data:


四、高级配置

4.1 环境变量文件

# docker-compose.yml
services:
  app:
    env_file:
      - .env

# .env
DATABASE_URL=mysql://root:password@db:3306/mydb
REDIS_URL=redis://redis:6379
SECRET_KEY=your-secret-key

4.2 网络配置

version: '3.8'

services:
  web:
    networks:
      - frontend
      - backend
  
  db:
    networks:
      - backend
  
  redis:
    networks:
      - backend

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

4.3 健康检查

services:
  db:
    image: mysql:8.0
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
  
  app:
    depends_on:
      db:
        condition: service_healthy


五、生产环境配置

version: '3.8'

services:
  app:
    build: .
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: '0.50'
          memory: 512M
    restart: always
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  db:
    image: mysql:8.0
    command: --default-authentication-plugin=mysql_native_password
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
    secrets:
      - db_root_password
    volumes:
      - mysql_data:/var/lib/mysql
    restart: always

secrets:
  db_root_password:
    file: ./secrets/db_root_password.txt


学习建议

  1. 先理解YAML语法
  2. 掌握基本服务配置
  3. 学习网络和数据卷
  4. 配置健康检查和重启策略
  5. 实践生产环境配置
返回首页