Skip to content

Docker Compose ​

1. 定位与版本 ​

Compose 用一个声明式模型管理同一应用的服务、网络、卷、配置和 Secret。现代命令是:

bash
docker compose version

不要再依赖旧的 Python docker-compose 二进制或旧式 version: "3" 文件语义。截至 2026-08-12,Compose 独立稳定版是 5.4.0;它与 Engine 29.7.2 是独立版本线。

2. 完整示例 ​

这是配置模板,未执行。先准备能拉取的业务镜像及 IMAGE_TAG;它须监听 8080、包含 /app/healthcheck,并按自己的程序合同读取数据库凭据。此模板未给 api 注入密码,需另按实际应用补齐,不能直接当作可启动工程。另在受限的 ./secrets/db_password.txt 保存非空数据库初始化密码。可跟读完整源码的例子见标准库双服务项目。

yaml
name: team-app

services:
  api:
    image: registry.example.internal/team/api:${IMAGE_TAG:?IMAGE_TAG is required}
    restart: unless-stopped
    init: true
    environment:
      APP_ENV: ${APP_ENV:-dev}
      DB_HOST: db
    ports:
      - "127.0.0.1:${API_PORT:-8080}:8080"
    read_only: true
    tmpfs:
      - /tmp:size=64m,mode=1770
    cap_drop:
      - ALL
    security_opt:
      - no-new-privileges:true
    healthcheck:
      test: ["CMD", "/app/healthcheck"]
      interval: 30s
      timeout: 3s
      retries: 3
      start_period: 20s
    depends_on:
      db:
        condition: service_healthy
    networks:
      - frontend
      - backend

  db:
    image: postgres:18-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: app
      POSTGRES_USER: app
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password
    volumes:
      - pgdata:/var/lib/postgresql
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app -d app"]
      interval: 10s
      timeout: 3s
      retries: 10
    networks:
      - backend

networks:
  frontend: {}
  backend:
    internal: true

volumes:
  pgdata: {}

secrets:
  db_password:
    file: ./secrets/db_password.txt

PostgreSQL 18 官方镜像将卷挂在 /var/lib/postgresql,PGDATA 默认位于其版本子目录;旧版数据须按官方迁移说明处理,不能只换标签。

本地文件 Secret 仍是宿主文件,不应提交 Git;设置严格权限并使用组织批准的 secret 管理。

3. 配置解析与验证 ​

bash
export IMAGE_TAG=git-a1b2c3d
docker compose config
docker compose config --services
docker compose config --images
docker compose config --environment

config 会完成合并和变量替换,输出可能含敏感值;CI 日志中谨慎使用。

4. 启动与更新 ​

bash
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail 100
docker compose logs -f api

重建:

bash
docker compose up -d --build
docker compose up -d --force-recreate api
docker compose up -d --no-deps api

--no-deps 只适合确认依赖无需同步变化的场景。

5. 停止与删除 ​

bash
docker compose stop
docker compose start
docker compose down

危险: docker compose down --volumes 会删除项目管理的卷,数据库数据可能永久丢失。普通重启不要使用 -v/--volumes。

down --rmi all 也会删除服务镜像,可能破坏离线回滚。

6. 环境变量与优先级 ​

容器环境同名变量的官方优先级从高到低:

  1. docker compose run -e;
  2. 经 shell 或 .env/--env-file 插值后的 environment/env_file;
  3. Compose environment;
  4. Compose env_file;
  5. 镜像 Dockerfile ENV。
bash
docker compose --env-file .env.uat config
docker compose run --rm -e LOG_LEVEL=debug api env

.env 既可用于 Compose 模型插值,又可能间接进入容器,两者不要混淆。敏感值不放 .env。

7. 多文件合并 ​

bash
docker compose \
  -f compose.yaml \
  -f compose.uat.yaml \
  config

docker compose \
  -f compose.yaml \
  -f compose.uat.yaml \
  up -d

合并规则因字段类型不同,列表不一定按直觉替换。每次先看最终 config。

8. Profile ​

yaml
services:
  debug-ui:
    image: example/debug-ui:1.0
    profiles: ["debug"]
bash
docker compose up -d
docker compose --profile debug up -d
docker compose --profile '*' config

Profile 适合可选开发工具,不应用来隐藏生产必需依赖。

9. 服务操作 ​

bash
docker compose exec api sh
docker compose run --rm api ./migrate
docker compose restart api
docker compose kill -s SIGQUIT api
docker compose top
docker compose events

run 创建一次性容器,默认不会发布服务的 ports;需要时显式 --service-ports,但先检查冲突。

10. 扩缩容 ​

bash
docker compose up -d --scale worker=3

被扩容服务不要设置固定 container_name 或固定宿主端口。Compose 的单机扩缩容不提供跨节点调度、自愈控制器和完整滚动发布。

11. depends_on 的边界 ​

默认启动顺序不代表依赖已经可用。使用 healthcheck + condition: service_healthy 可改善启动,但应用仍必须有:

  • 连接超时;
  • 有界重试与退避;
  • 幂等初始化;
  • 下游恢复后的重连。

12. Watch ​

开发环境:

bash
docker compose watch

在 Compose 文件中声明 develop.watch 的 sync/rebuild 规则。不要在生产把源码同步当发布流程。

13. 项目名 ​

项目名决定资源前缀。优先级包含 -p、顶层 name、环境变量和目录名:

bash
docker compose -p team-app-uat up -d
docker compose ls

CI 使用稳定且不冲突的项目名,执行 down 前先确认:

bash
docker compose -p team-app-uat ps

14. 生产注意 ​

  • 镜像使用不可变 tag,并记录 digest;关键部署可直接写 digest。
  • 不在 Compose 文件中写密码。
  • 配置资源限制、健康检查、日志轮转和停止超时。
  • 数据卷有备份与恢复演练。
  • 入口只绑定所需地址。
  • deploy 中部分字段只对特定平台/模式生效;用 docker compose config 和实际运行状态验证。
  • 单机 Compose 不等同于 Kubernetes 或 Swarm,高可用要求需匹配平台能力。

15. 排障 ​

bash
docker compose config
docker compose ps -a
docker compose logs --since 30m --timestamps
docker compose images
docker compose exec api getent hosts db
docker compose port api 8080
docker compose stats --no-stream

孤儿容器:

bash
docker compose up -d --remove-orphans

使用前核对项目名和配置文件,避免删除同项目下仍需保留的旧服务。

16. 官方参考 ​

继续阅读