在另一个Compose文件中导入Docker Compose文件

63

是否可能将一个docker-compose文件“导入”或链接到另一个docker-compose文件中?

假设我有两个文件:

# docker-compose-1.yml
services:
    A:
        # config
    B:
        # config
# docker-compose-2.yml
services:
    C:
        # config
    import: docker-compose-1.yml

通过运行docker-compose -f docker-compose-2.yml up,我想启动导入文件中指定的容器A、B和C。是否可以在不使用-f参数链接两个文件的情况下实现这一点?


2
目前还不可能。https://github.com/docker/compose/issues/318 - Esteban Garcia
@EstebanGarcia 是的,那正是我想要的。看起来这个问题已经存在将近5年了,所以可能不会有解决方案了... - Ondra K.
我有和你现在一样的需求,考虑编写一个编译器,通过遍历目录树递归地组合Docker Compose YAML文件。你已经想出解决方案了吗?如果没有,我可以分享我的方案,一旦它变得可呈现。 - jaaq
1
@jaaq 我没有,很遗憾。如果你实现了解决方案,能否分享一下?我会很高兴的。 - Ondra K.
2个回答

63

通过扩展

可以扩展或使用多个docker-compose文件及其服务,并在一个文件中将它们连接起来。您可以查看此链接,了解如何使用多个compose文件的其他用法。但是,如果没有像您提到的那样链接相关文件,您无法包含该文件。

这里,我定义了一个common-services.yaml:

version: '2'
   services:
      nginx_a:
         image: nginx:latest
         container_name: nginx
         ports:
           - 81:80
           - 1443:443

然后,我创建了一个docker-compose.yml文件,并包含了common-services.yml文件及其自己的服务。

services:
   nginx:
      extends:
         file: common-services.yml
         service: nginx_a

      nginx_b:
         image: nginx:latest
            container_name: nginx_b
            volumes:
            ports:
              - 82:80
              - 2443:443

.env技术

如果您想避免使用多个文件的链接用法,还有一种使用.env文件的技术。 我将使用.env技术重新编写上一个示例。

COMPOSE_PATH_SEPARATOR=:
COMPOSE_FILE=common-services.yml:docker-compose.yml

让我们在common-services.yml中举一个例子,添加另一个服务。

version: '2'
services:
  ngin_a:
    image: nginx:latest
    container_name: nginx_a
    ports:
      - 81:80
      - 1443:443

  redis_c:
    image: redis:latest
    container_name: redis_c
    ports:
      - 6381:6380

最后,将它们全部加载到docker-compose文件中,甚至不需要提及这些服务。

version: '2'
services:
   nginx_b:
     image: nginx:latest
     container_name: nginx_b
     ports:
       - 82:80
       - 2443:443
     env_file:
       - .env

最终,您将拥有三个正在运行的服务。


1
但在常规文件中,我仍然需要声明每个单独使用的服务,对吗?只有配置会被实际外部化。 - Ondra K.
.env 看起来是一个方便的技巧,但我不确定我是否正确理解了它。它似乎被用于外部化与服务相关的设置。实际上,我需要的是将多个相关服务组合在一起的 compose,这就是为什么我将它们分组到另一个 compose 文件中的原因。env_file 在特定服务下声明,因此据我所知,它只能加载与该服务相关的属性。或者我错了吗?换句话说,我不想在 docker-compose-2.yml 中提及服务 A 和 B。 - Ondra K.
@OndraK. 希望这不仅仅是关于配置的问题,我使用.env技术重写了之前的示例,并在我的笔记本电脑上进行了测试。您不需要再次在docker-compose文件中调用以前的服务。正如您所看到的,我在common-services文件中定义了Nginx和Redis服务,并且我只是在docker-compose文件中使用它们,而无需调用那些服务。 - Mehdi Hosseini
10
这在docker-compose V3上无效,但他们已经提出了一个问题来重新评估它-> https://github.com/moby/moby/issues/31101 - JVasques
扩展在Compose 3.9上非常顺畅。这应该是被接受的答案。 - LIvanov
显示剩余5条评论

12
Docker Compose的顶级元素include

{{link1:include在Docker Compose版本2.20及更高版本以及Docker Desktop版本4.22及更高版本中可用。}}

include:
  - shared/docker-compose.yaml
  - docker-compose.prod.yaml

services:
  webapp:
    depends_on:
      - redis

命令将不会提及文件作为参数-f
docker compose up -d 

4
太棒了,这似乎正是我4年前所需要的!:) 我会试用一下,谢谢。 - undefined
3
太棒了,这似乎正是我4年前所需要的!:) 我会试用一下,谢谢。 - Ondra K.
我真的很希望这个能够成功,但是不知道为什么,当我将包含了我想要的服务定义的yaml文件包含进去之后,再尝试运行该服务时,却只得到"没有这样的服务:<服务名称>"的错误信息。 - thinktt
你可以发布带有详细信息的新问题,并随意在这里分享链接,我们会仔细查看。 - Harsh Manvar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接