使用 include 选项拆分 Docker Compose 文件

注意
使用 include 选项需要 Docker Compose 为 2.20 (2023年7月发布)及以上版本
可使用 docker compose version 命令查看当前使用的 compose 版本

前言

Docker Compose 是管理多个容器服务的非常便捷的工具,写好一个 compose 文件即可一键启动与管理多个服务

但当要管理的服务数量较多时,单个 compose 文件难免会变得及其冗长,导致难以查阅和维护

为解决此问题,官方提供了 ExtendMerge 两种方式对 compose 进行拆分,但使用起来都不是非常的方便,也有各种各样的限制

例如冗长的启动命令

docker compose -f compose.yml -f compose.xxx.yml -f compose.yyy.yml -f compose.zzz.yml up -d

现在,官方提供了一个全新的选项 include 来更好地实现拆分

注意
docker compose 中 include 的原理类似于把被 include 文件的内容复制粘贴进当前的文件,所以与 ExtendMerge 的行为不同,同名的资源将不会被合并,而是直接报错 defines conflicting service/network,所以仅建议将 include 用于拆分文件

示例

基础示例

services:
A:
image: A
B:
image: B
C:
image: C

以上文件使用 include 选项可以拆分为以下文件:

# a.yml
services:
A:
image: nginx
# b.yml
services:
B:
image: nginx
# compose.yml
include:
- a.yml
- b.yml

services:
C:
image: nginx

此时使用 docker compose config 命令解析配置文件,可以看到 compose 文件被解析为了

❯ docker compose config
name: compose
services:
A:
image: nginx
networks:
default: null
B:
image: nginx
networks:
default: null
C:
image: nginx
networks:
default: null
networks:
default:
name: compose_default

使用 docker compose up -d 即可启动全部服务

相对路径解析示例

同时 include 选项也可以用于其他目录中的 compose 文件,相对路径都将会被解析为被 include 文件所在的路径

示例:

# ./a/compose.yml
services:
A:
image: nginx
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
# ./b/compose.yml
services:
B:
image: nginx
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
# ./compose.yml
include:
- ./a/compose.yml
- ./b/compose.yml

services:
C:
image: nginx
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf

使用 docker compose config 命令解析配置文件,可以看到 compose 文件被解析为了

❯ docker compose config
name: compose
services:
A:
image: nginx
networks:
default: null
volumes:
- type: bind
source: path_to_compose/a/nginx.conf
target: /etc/nginx/nginx.conf
bind:
create_host_path: true
B:
image: nginx
networks:
default: null
volumes:
- type: bind
source: path_to_compose/b/nginx.conf
target: /etc/nginx/nginx.conf
bind:
create_host_path: true
C:
image: nginx
networks:
default: null
volumes:
- type: bind
source: path_to_compose/nginx.conf
target: /etc/nginx/nginx.conf
bind:
create_host_path: true

networks:
default:
name: compose_default

个人经验

如果主 compose 文件与子 compose 文件在同一目录,可将子 compose 文件命名为 compose.xxx.yml 使其可被 VSCode 的 Docker 插件正确识别

参考

Include | Docker Docs

include top-level element