docker-compose 多个yml生效顺序

docker-compose.dev.yml 生效——Compose 按 -f 的书写顺序从左到右层层合并,后面的文件覆盖/追加到前面的结果上。所以标准约定就是:基础文件在前,环境覆盖文件(dev / prod / local)在后。后者(docker-compose.dev.yml)优先级更高。 Compose 把 -f 后面的文件按顺序叠加到前面的结果上,最后一份文件的话语权最大。

f4c4a298c8a5794bbfdf213b87bbb69d.png


1.同名service三种合并行为准则

字段类型 行为 典型字段
单值 后者整体替换前者 image、command、entrypoint、working_dir、container_name、restart、healthcheck.test
映射(键值) 逐键合并,同 key 后者赢,前者独有的保留 environment、labels、sysctls、extra_hosts、build.args
列表 追加拼接,不会整体替换 ports、expose、volumes、devices、dns、secrets、configs、depends_on

示例

1
2
3
4
5
6
7
8
9
10
# docker-compose.yml
services:
api:
image: myapp:1.0
command: node server.js
environment:
LOG_LEVEL: info
DB_HOST: db
ports:
- "8080:8080"
1
2
3
4
5
6
7
8
9
10
# docker-compose.dev.yml
services:
api:
image: myapp:dev # 覆盖 → myapp:dev
command: nodemon server.js # 覆盖 → nodemon
environment:
LOG_LEVEL: debug # 覆盖 → debug(DB_HOST 仍保留)
DEBUG: "1" # 新增
ports:
- "9229:9229" # 追加 → 8080 和 9229 都存在

2.验证方式

1
2
3
4
5
# 2.1查看合并后的最终配置(最可靠)
docker compose -f docker-compose.yml -f docker-compose.dev.yml config

# 2.2只看 service 列表
docker compose -f docker-compose.yml -f docker-compose.dev.yml config --services

3.注意的坑

  • 列表是追加,不是替换:想改掉基础文件里的端口/挂载,直接在 dev 里写新值是做不到的,结果会变成两个都存在;同宿主端口重复会直接报端口冲突。要么改基础文件,要么用 !reset 语法(Compose v2.24+ 支持 ports: !reset [])清空后再写。
  • 相对路径基准:build.context、env_file、volumes 的相对路径是相对项目目录(默认即第一个 -f 文件所在目录)解析,而不是各文件自己的目录。跨目录放 compose 文件时很容易踩坑,用 docker compose config 看解析结果最稳。
  • --build 与合并无关,只影响是否重新构建镜像。
  • 用 COMPOSE_FILE=a.yml:b.yml 环境变量时逻辑相同,也是从左到右。