Skip to content

Docker Compose

Compose 用一个 YAML 文件定义并运行多个容器,是单机多容器应用的标准做法。
本手册采用 Compose v2 语法(命令为 docker compose,注意中间是空格)。

快速上手

bash
# 在 docker-compose.yml 所在目录
docker compose up -d        # 构建并后台启动
docker compose ps           # 查看服务状态
docker compose logs -f      # 查看日志
docker compose down         # 停止并删除容器/网络

完整示例:Web + API + 数据库

yaml
# docker-compose.yml
services:
  db:
    image: mysql:8
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: app
    volumes:
      - dbdata:/var/lib/mysql
    networks:
      - backend
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

  api:
    build: ./api              # 从 ./api 目录的 Dockerfile 构建
    restart: unless-stopped
    environment:
      DATABASE_URL: mysql://db:3306/app
    ports:
      - "8080:8080"
    depends_on:
      db:
        condition: service_healthy   # 等 db 健康后才启动
    networks:
      - backend

  web:
    build: ./web
    ports:
      - "80:80"
    depends_on:
      - api
    networks:
      - backend

volumes:
  dbdata:

networks:
  backend:

关键字段说明

字段作用
services定义各容器服务
image使用的镜像(与 build 二选一或结合)
build构建上下文/ Dockerfile 路径
command / entrypoint覆盖启动命令
environment / env_file环境变量
ports端口映射 "宿主:容器"
expose仅对网络内服务开放端口
volumes挂载(卷或绑定)
networks加入的网络
depends_on启动顺序依赖
restart重启策略
healthcheck健康检查
container_name指定容器名(不写则自动命名)
profiles按需启用的服务组

常用命令

bash
docker compose up -d              # 启动(-d 后台)
docker compose up -d --build      # 重新构建并启动
docker compose up -d --force-recreate   # 强制重建容器
docker compose up -d db           # 只启动某个服务

docker compose ps                 # 状态
docker compose logs -f            # 全部日志
docker compose logs -f api        # 单个服务日志
docker compose exec api sh        # 进入服务容器
docker compose run --rm api bash  # 临时运行一次性命令

docker compose down               # 停止并删除容器、网络
docker compose down -v            # 连同卷一起删除(慎用)
docker compose stop               # 仅停止,不删除
docker compose start              # 再次启动
docker compose restart            # 重启

docker compose pull               # 拉取镜像
docker compose build              # 构建镜像
docker compose config             # 校验并展开配置(排查用)
docker compose top                # 查看进程

docker compose ps --services      # 列出服务名

多环境与覆盖

bash
# 基础配置 + 环境覆盖文件
docker compose -f docker-compose.yml -f docker-compose.override.yml up -d
# 生产环境
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

docker-compose.override.yml自动被读取,常用于本地开发覆盖(如挂载源码)。

环境变量与 .env

Compose 会自动读取同目录 .env 文件:

bash
# .env
MYSQL_PASSWORD=secret123
PORT=8080
yaml
services:
  db:
    image: mysql:8
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_PASSWORD}   # 引用 .env
  api:
    ports:
      - "${PORT}:8080"

注意:.envenvironment:(容器内变量)是两回事;
前者供 Compose 文件内 ${} 替换,后者注入容器。

命名网络与自动 DNS

Compose 会创建名为「项目名_网络名」的网络,服务间直接用服务名互访(如 db:3306),无需配置 IP。

健康检查与依赖顺序

yaml
depends_on:
  db:
    condition: service_healthy    # 等 db 健康
  cache:
    condition: service_started    # 等 cache 启动即可
  worker:
    condition: service_completed_successfully  # 等 worker 成功退出

depends_on 只保证顺序,不保证服务“就绪”;真正的就绪判断靠 healthcheck + condition: service_healthy

Compose vs 手动 docker run

维度手动 runCompose
多容器逐条命令,易漏一个文件全定义
可复现强(版本可控)
启停逐个一键 up/down
网络手动建自动创建与管理
协作靠文档YAML 即文档

最佳实践

  1. docker-compose.yml 纳入版本管理。
  2. .env 管理敏感配置,别硬编码密码。
  3. 生产环境用 restart: unless-stopped
  4. 数据库等有状态服务配 healthcheck 和命名卷。
  5. docker compose config 校验配置再上线。