Docker Compose 的两个版本

目前 Docker Compose 有两个主要版本:

  • Docker Compose V1:传统版本,命令为 docker-compose
  • Docker Compose V2:新版本,命令为 docker compose(无连字符)
# 检查版本
docker-compose --version  # V1
docker compose version    # V2

一个简单的 Web 应用示例

让我们从一个简单的 Web 应用开始,它包含一个 Web 服务和一个数据库服务。

创建项目结构

my-web-app/
├── docker-compose.yaml
├── web/
│   ├── Dockerfile
│   ├── app.py
│   └── requirements.txt

编写 Web 应用 (app.py)

from flask import Flask, jsonify
import os
import pymysql

app = Flask(__name__)

@app.route('/')
def hello():
    return jsonify(message="Hello from Flask!")

@app.route('/db')
def db_connection():
    connection = pymysql.connect(
        host=os.environ.get('DB_HOST', 'db'),
        user=os.environ.get('DB_USER', 'user'),
        password=os.environ.get('DB_PASSWORD', 'password'),
        database=os.environ.get('DB_NAME', 'mydb'),
        cursorclass=pymysql.cursors.DictCursor
    )
    
    try:
        with connection.cursor() as cursor:
            cursor.execute("SELECT 1 as result")
            result = cursor.fetchone()
            return jsonify(db_connection="成功", result=result)
    except Exception as e:
        return jsonify(db_connection="失败", error=str(e))
    finally:
        connection.close()

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

依赖文件 (requirements.txt)

flask==2.0.1
pymysql==1.0.2

Dockerfile

FROM python:3.9-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY app.py .

CMD ["python", "app.py"]

Docker Compose 文件 (docker-compose.yaml)

version: '3'

services:
  web:
    build: ./web
    ports:
      - "5000:5000"
    environment:
      - DB_HOST=db
      - DB_USER=user
      - DB_PASSWORD=password
      - DB_NAME=mydb
    depends_on:
      - db
    restart: always

  db:
    image: mysql:5.7
    environment:
      - MYSQL_ROOT_PASSWORD=rootpassword
      - MYSQL_DATABASE=mydb
      - MYSQL_USER=user
      - MYSQL_PASSWORD=password
    volumes:
      - db_data:/var/lib/mysql
    restart: always

volumes:
  db_data:

Docker Compose 核心概念

1. 服务 (Services)

服务是应用的组成部分,在上面的例子中,我们定义了两个服务:

  • web:一个 Flask 应用,从 Dockerfile 构建
  • db:一个 MySQL 数据库,使用官方镜像

每个服务都可以配置:

  • 镜像或构建上下文
  • 端口映射
  • 环境变量
  • 依赖关系
  • 重启策略等

2. 网络 (Networks)

Docker Compose 会自动创建一个网络,所有服务都连接到这个网络。服务可以通过服务名称相互访问,如 web 服务可以通过 db 主机名访问数据库。

如果需要自定义网络,可以这样配置:

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

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

3. 数据卷 (Volumes)

数据卷用于持久化数据或在容器间共享数据:

volumes:
  db_data:  # 命名卷,数据会在容器重启后保留

也可以使用绑定挂载,将主机目录挂载到容器:

volumes:
  - ./config:/app/config  # 绑定挂载

常用 Docker Compose 命令

启动服务

# 构建并启动所有服务(前台)
docker compose up

# 构建并启动所有服务(后台)
docker compose up -d

# 仅构建镜像,不启动
docker compose build

停止服务

# 停止服务但不删除容器
docker compose stop

# 停止服务并删除容器
docker compose down

# 停止服务并删除容器、网络、数据卷
docker compose down -v

查看状态

# 查看服务状态
docker compose ps

# 查看日志
docker compose logs

# 实时查看日志
docker compose logs -f

执行命令

# 在 web 服务中执行命令
docker compose exec web bash

# 在 web 服务中运行一次性命令
docker compose run --rm web python -c "print('Hello')"

实用示例:WordPress 博客

下面是一个更实用的示例,部署 WordPress 博客:

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
    depends_on:
      - db
    restart: always

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

volumes:
  db_data:

使用 docker compose up -d 启动后,访问 http://localhost:8080 即可看到 WordPress 安装界面。

高级功能

1. 环境变量

可以使用 .env 文件存储环境变量:

# .env 文件
DB_PASSWORD=mysecretpassword
WORDPRESS_PORT=8080

然后在 docker-compose.yaml 中引用:

services:
  wordpress:
    ports:
      - "${WORDPRESS_PORT}:80"

2. 健康检查

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

3. 扩展服务

# 启动 3 个 web 服务实例
docker compose up -d --scale web=3

最佳实践

  1. 使用版本控制:将 docker-compose.yaml 纳入版本控制系统
  2. 环境变量分离:使用 .env 文件存储敏感信息
  3. 合理命名:为服务、网络和卷使用有意义的名称
  4. 限制资源使用:设置内存和 CPU 限制
  5. 使用健康检查:确保服务正常运行

结论

Docker Compose 极大地简化了多容器应用的部署和管理。通过简单的 YAML 配置,你可以定义完整的应用栈,包括服务、网络和数据卷。

无论是开发环境、测试环境还是小型生产环境,Docker Compose 都是一个强大且易用的工具。对于更大规模的部署,可以考虑使用 Kubernetes 或 Docker Swarm 等容器编排平台。

希望这篇指南能帮助你快速上手 Docker Compose!