不同的 env 文件但相同的 yml 与 Docker Compose?
Different env-file but same yml with Docker Compose?
我发现我有多个环境(例如测试和生产)很常见,但我希望启动的 Docker 容器在两个环境中都是相同的。唯一的区别是我想使用 env-file
指定的应用程序配置。因为我有多个容器和它们之间的依赖关系,所以我想使用 docker-compose. But afaik I can only specify an env-file
inside the docker-compose.yml
file (see docs)。如果是这种情况,那么我需要将我的原始 docker-compose.yml
克隆到两个不同的文件(一个用于测试,一个用于生产),只是为了指向不同的 env 文件。这意味着我必须维护两个 docker-compose.yml
文件而不是一个文件,如果我进行任何更改,我需要更新这两个文件。
这真的是设计的吗?当我指定 docker-compose up
或 docker-compose run
时,为什么 docker-compose
不让我指定 --env-file
?
请参阅下面的更新 #2。这现在成为可能!
这是 Docker Compose 的一个非常受欢迎的功能。不幸的是,目前的答案是你不能。我建议订阅这些 GitHub 问题,以便更好地了解何时以及是否实施此功能:
- https://github.com/docker/compose/issues/495
- https://github.com/docker/compose/pull/76
- https://github.com/docker/compose/pull/845
问题 #495 实际上是目前他们的问题存储库中评论最多的问题。你绝对不是唯一想这样做的人。
更新:
最新的问题跟踪在 https://github.com/docker/compose/issues/1377。
更新#2:
此功能已合并并从 Docker Compose 1.5.0 开始可用。有关使用信息,请参阅 https://github.com/docker/compose/blob/129092b7/docs/yml.md#variable-substitution。
它不是直接从命令行包含,但如果您需要在 the #1765 merge (the fix for #1377) makes it into a release, you can use the extends
directive along with the env_file
directive. For convenience, the files from the simple examples below are reproduced in this repository 之前进行变通。
愚蠢的简单例子
base.yml
base:
image: busybox
command: bash -c 'echo "${WHO:-Simon} says, \"${SHOUTOUT:-Silence is golden.}\""'
one.env
WHO=Da Schwartz
SHOUTOUT=Get to...
one_glue.yml
one:
extends:
file: base.yml
service: base
env_file:
- one.env
two.env
WHO=Da Schwartz
SHOUTOUT=...da choppa!
two_glue.yml
two:
extends:
file: base.yml
service: base
env_file:
- two.env
使用
% for i in base one_glue two_glue ; do docker-compose --file "${i}.yml" up ; done
Recreating dockercomposeextendsenv_base_1...
Attaching to dockercomposeextendsenv_base_1
base_1 | Simon says, "Silence is golden."
dockercomposeextendsenv_base_1 exited with code 0
Gracefully stopping... (press Ctrl+C again to force)
Recreating dockercomposeextendsenv_one_1...
Attaching to dockercomposeextendsenv_one_1
one_1 | Da Schwartz says, "Get to..."
dockercomposeextendsenv_one_1 exited with code 0
Gracefully stopping... (press Ctrl+C again to force)
Recreating dockercomposeextendsenv_two_1...
Attaching to dockercomposeextendsenv_two_1
two_1 | Da Schwartz says, "...da choppa!"
dockercomposeextendsenv_two_1 exited with code 0
Gracefully stopping... (press Ctrl+C again to force)
更简单的例子
如果您受益于使用 .env
文件,则以上内容有效。如果您不受此限制,您可以将环境变量设置保留在特定于环境的 "glue" .yml
文件中:
red_glue.yml
red:
extends:
file: base.yml
service: base
environment:
- WHO=Stallion
- SHOUTOUT=I am...
blue_glue.yml
blue:
extends:
file: base.yml
service: base
environment:
- WHO=Stallion
- SHOUTOUT=...the law!
使用
% for i in red_glue blue_glue ; do docker-compose --file "${i}.yml" up ; done
Creating dockercomposeextendsenv_red_1...
Attaching to dockercomposeextendsenv_red_1
red_1 | Stallion says, "I am..."
dockercomposeextendsenv_red_1 exited with code 0
Gracefully stopping... (press Ctrl+C again to force)
Creating dockercomposeextendsenv_blue_1...
Attaching to dockercomposeextendsenv_blue_1
blue_1 | Stallion says, "...the law!"
dockercomposeextendsenv_blue_1 exited with code 0
Gracefully stopping... (press Ctrl+C again to force)
有点复杂
对于它的价值,此答案中描述的方法允许在每个实例的基础上使用不同的 .env
文件,而不是 per-invocation/environment。 (不过,我不确定这在实践中有多大好处。)换句话说,您可以这样做:
testing.yml
# Only instance1 and instance2 are needed for testing
instance1:
extends:
file: base.yml
service: base
env_file:
- test.env # environment-specific
- instance1_test.env # instance-specific
instance2:
extends:
file: base.yml
service: base
env_file:
- test.env
- instance2_test.env
production.yml
# All four instances are used for production
instance1:
extends:
file: base.yml
service: base
env_file:
- prod.env # environment-specific
- instance1_prod.env # instance-specific
instance2:
extends:
file: base.yml
service: base
env_file:
- prod.env
- instance2_prod.env
instance3:
extends:
file: base.yml
service: base
env_file:
- prod.env
- instance3_prod.env
instance4:
extends:
file: base.yml
service: base
env_file:
- prod.env
- instance4_prod.env
您可以开始看到 extends
非常强大,比 #1765 merge 所允许的要强大得多。
Update Apr 2020
Docker Compose v3+ deprecated the extends
feature.
很好清楚的例子,但是这最初对我不起作用,直到我更新 base.yml 调用 ash shell。
base.yml
base:
image: busybox
command: ash -c 'echo "${WHO:-Simon} says, \"${SHOUTOUT:-Silence is golden.}\""'
我发现我有多个环境(例如测试和生产)很常见,但我希望启动的 Docker 容器在两个环境中都是相同的。唯一的区别是我想使用 env-file
指定的应用程序配置。因为我有多个容器和它们之间的依赖关系,所以我想使用 docker-compose. But afaik I can only specify an env-file
inside the docker-compose.yml
file (see docs)。如果是这种情况,那么我需要将我的原始 docker-compose.yml
克隆到两个不同的文件(一个用于测试,一个用于生产),只是为了指向不同的 env 文件。这意味着我必须维护两个 docker-compose.yml
文件而不是一个文件,如果我进行任何更改,我需要更新这两个文件。
这真的是设计的吗?当我指定 docker-compose up
或 docker-compose run
时,为什么 docker-compose
不让我指定 --env-file
?
请参阅下面的更新 #2。这现在成为可能!
这是 Docker Compose 的一个非常受欢迎的功能。不幸的是,目前的答案是你不能。我建议订阅这些 GitHub 问题,以便更好地了解何时以及是否实施此功能:
- https://github.com/docker/compose/issues/495
- https://github.com/docker/compose/pull/76
- https://github.com/docker/compose/pull/845
问题 #495 实际上是目前他们的问题存储库中评论最多的问题。你绝对不是唯一想这样做的人。
更新:
最新的问题跟踪在 https://github.com/docker/compose/issues/1377。
更新#2:
此功能已合并并从 Docker Compose 1.5.0 开始可用。有关使用信息,请参阅 https://github.com/docker/compose/blob/129092b7/docs/yml.md#variable-substitution。
它不是直接从命令行包含,但如果您需要在 the #1765 merge (the fix for #1377) makes it into a release, you can use the extends
directive along with the env_file
directive. For convenience, the files from the simple examples below are reproduced in this repository 之前进行变通。
愚蠢的简单例子
base.yml
base:
image: busybox
command: bash -c 'echo "${WHO:-Simon} says, \"${SHOUTOUT:-Silence is golden.}\""'
one.env
WHO=Da Schwartz
SHOUTOUT=Get to...
one_glue.yml
one:
extends:
file: base.yml
service: base
env_file:
- one.env
two.env
WHO=Da Schwartz
SHOUTOUT=...da choppa!
two_glue.yml
two:
extends:
file: base.yml
service: base
env_file:
- two.env
使用
% for i in base one_glue two_glue ; do docker-compose --file "${i}.yml" up ; done
Recreating dockercomposeextendsenv_base_1...
Attaching to dockercomposeextendsenv_base_1
base_1 | Simon says, "Silence is golden."
dockercomposeextendsenv_base_1 exited with code 0
Gracefully stopping... (press Ctrl+C again to force)
Recreating dockercomposeextendsenv_one_1...
Attaching to dockercomposeextendsenv_one_1
one_1 | Da Schwartz says, "Get to..."
dockercomposeextendsenv_one_1 exited with code 0
Gracefully stopping... (press Ctrl+C again to force)
Recreating dockercomposeextendsenv_two_1...
Attaching to dockercomposeextendsenv_two_1
two_1 | Da Schwartz says, "...da choppa!"
dockercomposeextendsenv_two_1 exited with code 0
Gracefully stopping... (press Ctrl+C again to force)
更简单的例子
如果您受益于使用 .env
文件,则以上内容有效。如果您不受此限制,您可以将环境变量设置保留在特定于环境的 "glue" .yml
文件中:
red_glue.yml
red:
extends:
file: base.yml
service: base
environment:
- WHO=Stallion
- SHOUTOUT=I am...
blue_glue.yml
blue:
extends:
file: base.yml
service: base
environment:
- WHO=Stallion
- SHOUTOUT=...the law!
使用
% for i in red_glue blue_glue ; do docker-compose --file "${i}.yml" up ; done
Creating dockercomposeextendsenv_red_1...
Attaching to dockercomposeextendsenv_red_1
red_1 | Stallion says, "I am..."
dockercomposeextendsenv_red_1 exited with code 0
Gracefully stopping... (press Ctrl+C again to force)
Creating dockercomposeextendsenv_blue_1...
Attaching to dockercomposeextendsenv_blue_1
blue_1 | Stallion says, "...the law!"
dockercomposeextendsenv_blue_1 exited with code 0
Gracefully stopping... (press Ctrl+C again to force)
有点复杂
对于它的价值,此答案中描述的方法允许在每个实例的基础上使用不同的 .env
文件,而不是 per-invocation/environment。 (不过,我不确定这在实践中有多大好处。)换句话说,您可以这样做:
testing.yml
# Only instance1 and instance2 are needed for testing
instance1:
extends:
file: base.yml
service: base
env_file:
- test.env # environment-specific
- instance1_test.env # instance-specific
instance2:
extends:
file: base.yml
service: base
env_file:
- test.env
- instance2_test.env
production.yml
# All four instances are used for production
instance1:
extends:
file: base.yml
service: base
env_file:
- prod.env # environment-specific
- instance1_prod.env # instance-specific
instance2:
extends:
file: base.yml
service: base
env_file:
- prod.env
- instance2_prod.env
instance3:
extends:
file: base.yml
service: base
env_file:
- prod.env
- instance3_prod.env
instance4:
extends:
file: base.yml
service: base
env_file:
- prod.env
- instance4_prod.env
您可以开始看到 extends
非常强大,比 #1765 merge 所允许的要强大得多。
Update Apr 2020
Docker Compose v3+ deprecated the
extends
feature.
很好清楚的例子,但是这最初对我不起作用,直到我更新 base.yml 调用 ash shell。
base.yml
base:
image: busybox
command: ash -c 'echo "${WHO:-Simon} says, \"${SHOUTOUT:-Silence is golden.}\""'