当使用多个 `--file` 选项时,如何设置 Docker Compose `env_file` 相对于 `.yml` 文件?

How to set Docker Compose `env_file` relative to `.yml` file when multiple `--file` option is used?

我正在尝试将我的 env_file 配置设置为相对于多个 docker-compose.yml 文件位置中的每一个,而不是相对于第一个 docker-compose.yml.

文档 (https://docs.docker.com/compose/compose-file/compose-file-v3/#env_file) 表明这应该是可能的:

If you have specified a Compose file with docker-compose -f FILE, paths in env_file are relative to the directory that file is in.

例如,当我发出

docker compose \
  --file docker-compose.yml \
  --file backend/docker-compose.yml \
  --file docker-compose.override.yml up

第二个(即backend/docker-compose.yml)和第三个(即docker-compose.override.yml)中的所有env_file路径都是相对于第一个文件的位置(即docker-compose.yml)

我希望每个 docker-compose.yml 文件中的 env_file 设置与定义它的文件相关。

这可能吗?

感谢您的宝贵时间

如果你对上下文感到好奇:

我想要一个独立的后端存储库,后端开发人员可以在不需要前端容器的情况下直接使用它。 前端 repo 将后端 repo 作为 Git 子模块拉入,因为前端容器需要后端容器作为依赖项。 这是我的 2 个回购协议:

后端组织如下:

/docker-compose.yml
/docker-compose.override.yml

前端是这样组织的:

/docker-compose.yml
/docker-compose.override.yml
/backend/ # pulled in as a Git submodule
/backend/docker-compose.yml
/backend/docker-compose.override.yml

如果我将 env_file 放入 docker-compose.override.yml 文件,一切正常。后端的覆盖 env_file 将相对于后端 docker-compose.yml。前端的覆盖 env_file 将相对于前端 docker-compose.yml。前端永远不会使用后端的 docker-compose.override.yml.

但我想将后端的 env_file 设置改为后端的 docker-compose.yml,以便需要后端容器的项目可以继承并仅使用它的默认值。如果依赖项目想要覆盖后端的 env_file,那么它可以在依赖项目的 docker-compose.override.yml.

中这样做

我希望这是有道理的。

如果有其他组织模式 Docker-Compose 项目可以处理这种情况,请告诉我。

事实证明,已经有关于此的问题和讨论:

线程指出这是预期的行为并在此处记录:https://docs.docker.com/compose/extends/#understanding-multiple-compose-files

When you use multiple configuration files, you must make sure all paths in the files are relative to the base Compose file (the first Compose file specified with -f). This is required because override files need not be valid Compose files. Override files can contain small fragments of configuration. Tracking which fragment of a service is relative to which path is difficult and confusing, so to keep paths easier to understand, all paths must be defined relative to the base file.

该讨论中有一个非常有效的解决方法: https://github.com/docker/compose/issues/3874#issuecomment-470311052

解决方法是使用具有默认值的 ENV 变量:

  • ${PROXY:-.}/haproxy/conf:/usr/local/etc/haproxy

或者在我的情况下:

  env_file:
    - ${BACKEND_BASE:-.}/.env

希望对其他人有所帮助

如果有人对完整代码感兴趣: backenddocker-compose.yml: https://gitlab.com/starting-spark/porter/backend/-/blob/3.4.3/docker-compose.yml#L13-14
backenddocker-compose.override.yml: https://gitlab.com/starting-spark/porter/backend/-/blob/3.4.3/docker-compose.override.yml#L3-4
backend.env: https://gitlab.com/starting-spark/porter/backend/-/blob/3.4.3/.env
frontenddocker-compose.yml: https://gitlab.com/starting-spark/porter/frontend/-/blob/3.2.2/docker-compose.yml#L5-6
frontenddocker-compose.override.yml: https://gitlab.com/starting-spark/porter/frontend/-/blob/3.2.2/docker-compose.override.yml#L3-4
frontend.env: https://gitlab.com/starting-spark/porter/frontend/-/blob/3.2.2/.env#L16