与Docker Compose不同的env文件但是相同的yml?

Joh*_*han 25 docker docker-compose

我发现我有多个环境(例如test和prod)很常见,但我希望启动的Docker容器在两种环境中都是相同的.唯一的区别是我想要使用的应用程序配置env-file.由于我有多个容器和它们之间的依赖关系,我想使用docker-compose.但是afaik我只能指定文件env-file内部docker-compose.yml(参见docs).如果是这种情况,那么我需要将原始docker-compose.yml文件克隆到两个不同的文件(一个用于测试,一个用于prod),只是为了指向不同的env文件.这意味着我必须维护两个docker-compose.yml文件而不是一个,如果我做了任何更改,我需要更新这两个文件.

这真的是根据设计吗?为什么docker-compose不让我指明--env-file我什么时候docker-compose updocker-compose run

And*_*inn 17

请参阅下面的更新#2.现在可以了!

这是Docker Compose非常需要的功能.不幸的是,目前的答案是你不能.我建议订阅这些GitHub问题,以便更好地了解何时以及是否实现此功能:

问题#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.

  • @AndyShinn原始问题是指定一个环境文件的命令行选项,但尚未出现在docker-compose中,即使在最新的v1.16.1中也没有.没有downvoting,但我发现更新#2非常令人困惑. (5认同)
  • 只需将`env-file`作为环境变量:`MYENVFILE = production.env docker-compose up` (2认同)

pos*_*ita 6

它不是命令行的直接包含,但是如果你需要在#1765合并之前进行解决(#1377的修复)使它成为一个版本,你可以使用该extends指令env_file指令.为方便起见,以下简单示例中的文件将在此存储库中重现.

愚蠢的简单例子

base.yml

base:
    image: busybox
    command: bash -c 'echo "${WHO:-Simon} says, \"${SHOUTOUT:-Silence is golden.}\""'
Run Code Online (Sandbox Code Playgroud)

one.env

WHO=Da Schwartz
SHOUTOUT=Get to...
Run Code Online (Sandbox Code Playgroud)

one_glue.yml

one:
    extends:
        file: base.yml
        service: base
    env_file:
        - one.env
Run Code Online (Sandbox Code Playgroud)

two.env

WHO=Da Schwartz
SHOUTOUT=...da choppa!
Run Code Online (Sandbox Code Playgroud)

two_glue.yml

two:
    extends:
        file: base.yml
        service: base
    env_file:
        - two.env
Run Code Online (Sandbox Code Playgroud)

使用

% 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)
Run Code Online (Sandbox Code Playgroud)

更简单的例子

如果您从使用.env文件中受益,则上述工作正常.如果您不是那么有限,可以将环境变量设置保存在特定于环境的"粘合" .yml文件中:

red_glue.yml

red:
    extends:
        file: base.yml
        service: base
    environment:
        - WHO=Stallion
        - SHOUTOUT=I am...
Run Code Online (Sandbox Code Playgroud)

blue_glue.yml

blue:
    extends:
        file: base.yml
        service: base
    environment:
        - WHO=Stallion
        - SHOUTOUT=...the law!
Run Code Online (Sandbox Code Playgroud)

使用

% 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)
Run Code Online (Sandbox Code Playgroud)

有点复杂

对于它的价值,本答案中描述的方法允许.env基于每个实例的不同文件,而不是每个调用/环境.(但我不确定这在实践中有多么有用.)换句话说,你可以这样做:

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

您可以开始看到它extends非常强大,远远超过#1765合并所允许的范围.

  • 不幸的是,Docker 人员还没有将扩展功能从 docker-compose 版本 2 传播到 dc 版本 3,至少现在还没有,因此在某种程度上降低了这里的实用性。 (2认同)