Skip to content

Docker Compose 基础

Docker Compose 是用于定义和管理多容器 Docker 应用的工具,通过一个 YAML 文件描述所有服务,一条命令即可启动整个应用。

为什么需要 Docker Compose

管理单个容器,直接使用 docker run 即可。但实际应用往往由多个服务组成:

# 没有 Compose:需要手动执行多条命令
docker network create app-net
docker volume create mysql-data
docker run -d --name mysql --network app-net -v mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=secret mysql:8.0
docker run -d --name redis --network app-net redis:alpine
docker run -d --name api --network app-net -p 3000:3000 -e DB_HOST=mysql myapi:latest
docker run -d --name nginx --network app-net -p 80:80 nginx:alpine

# 使用 Compose:一条命令
docker compose up -d

安装

Docker Compose v2(内置插件)

Docker Desktop 已内置,Linux 需要单独安装:

bash
# 检查是否已安装
docker compose version

# Linux 安装(作为 Docker 插件)
sudo apt-get install docker-compose-plugin  # Debian/Ubuntu
sudo yum install docker-compose-plugin       # CentOS/RHEL

# 或通过 GitHub 下载
DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
mkdir -p $DOCKER_CONFIG/cli-plugins
curl -SL https://github.com/docker/compose/releases/latest/download/docker-compose-linux-x86_64 \
  -o $DOCKER_CONFIG/cli-plugins/docker-compose
chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose

注意:Docker Compose v2 命令是 docker compose(中间有空格),旧版 v1 是 docker-compose(连字符)。

第一个 Compose 文件

项目结构:

myapp/
├── docker-compose.yml
├── api/
│   ├── Dockerfile
│   └── app.js
└── nginx/
    └── default.conf

docker-compose.yml:

yaml
services:
  # 数据库
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: myapp
    volumes:
      - mysql-data:/var/lib/mysql
    networks:
      - backend

  # 缓存
  redis:
    image: redis:alpine
    networks:
      - backend

  # 后端 API
  api:
    build: ./api          # 从 ./api 目录的 Dockerfile 构建
    ports:
      - "3000:3000"
    environment:
      DB_HOST: mysql
      DB_PASSWORD: secret
      REDIS_URL: redis://redis:6379
    depends_on:
      - mysql
      - redis
    networks:
      - backend
      - frontend

  # 反向代理
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
    depends_on:
      - api
    networks:
      - frontend

volumes:
  mysql-data:

networks:
  backend:
  frontend:

核心命令

bash
# 启动所有服务(后台运行)
docker compose up -d

# 启动并查看日志
docker compose up

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

# 强制重新构建镜像并启动
docker compose up -d --build

# 查看服务状态
docker compose ps

# 查看所有服务日志
docker compose logs

# 跟踪指定服务日志
docker compose logs -f api

# 停止所有服务
docker compose stop

# 停止并删除容器、网络
docker compose down

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

# 进入指定服务的容器
docker compose exec api sh

# 在服务中执行命令(不进入容器)
docker compose exec mysql mysql -uroot -psecret

# 重启指定服务
docker compose restart api

# 扩展服务实例数
docker compose scale api=3  # 已弃用,推荐使用 up
docker compose up -d --scale api=3

实战示例:WordPress

yaml
# docker-compose.yml
services:
  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: wordpress_root_password
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress_password
    volumes:
      - db-data:/var/lib/mysql

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

volumes:
  db-data:
  wordpress-data:
bash
# 启动
docker compose up -d

# 访问:http://localhost:8080

使用环境变量文件

bash
# .env 文件(自动加载)
MYSQL_ROOT_PASSWORD=secret
MYSQL_DATABASE=myapp
API_PORT=3000
yaml
# docker-compose.yml
services:
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
  
  api:
    build: .
    ports:
      - "${API_PORT}:3000"

多环境配置

bash
# 基础配置
docker-compose.yml

# 开发环境覆盖(自动合并)
docker-compose.override.yml

# 生产环境
docker-compose.prod.yml

# 使用指定配置文件
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

docker-compose.override.yml 示例(开发环境):

yaml
services:
  api:
    volumes:
      - ./src:/app/src    # 挂载源码(开发热更新)
    environment:
      NODE_ENV: development
    command: nodemon app.js

  mysql:
    ports:
      - "3306:3306"       # 开发环境暴露端口,方便调试

健康检查与依赖等待

yaml
services:
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: secret
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

  api:
    build: .
    depends_on:
      mysql:
        condition: service_healthy  # 等待 mysql 健康后再启动

总结

Docker Compose 的核心价值:

  • 用 YAML 声明式描述多服务应用
  • 一条命令管理整个应用的生命周期
  • 内置网络和服务发现
  • 支持多环境配置

常用命令记忆口诀:up 启动,down 停止,ps 状态,logs 日志,exec 进入。

下一节详细介绍 Compose 文件的所有配置项。