27

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

这真的是按照设计吗?为什么docker-compose不让我指定--env-file什么时候做docker-compose upor docker-compose run

4

3 回答 3

18

请参阅下面的更新 #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

于 2015-03-15T17:32:07.537 回答
7

它不是从命令行直接包含的,但如果您需要在#1765 合并(对#1377的修复)使其发布之前需要解决方法,您可以将extends指令与指令一起env_file使用。为方便起见,以下简单示例中的文件在此存储库中复制。

愚蠢的简单例子

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文件中受益,则上述方法有效。如果您不受限制,则可以将环境变量设置保留在特定于环境的“胶水”.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在每个实例的基础上使用不同的文件,而不是每个调用/环境。(但是,我不确定这在实践中有多有用。)换句话说,您可以执行以下操作:

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 合并所允许的要强大得多。


2020 年 4 月更新

Docker Compose v3+已弃用该extends功能

于 2015-08-08T02:27:19.810 回答
0

很好的清晰示例,但是在我更新 base.yml 以调用灰壳之前,这最初对我不起作用。

基础.yml

base:
    image: busybox
    command: ash -c 'echo "${WHO:-Simon} says, \"${SHOUTOUT:-Silence is golden.}\""'
于 2015-11-29T13:54:23.987 回答