Docker compose docker compose env_文件仅加载.env,而不是特定名称

Docker compose docker compose env_文件仅加载.env,而不是特定名称,docker-compose,environment-variables,Docker Compose,Environment Variables,我真的不理解docker compose在环境变量文件方面的行为 我已经为运行2 flask应用程序的简单echo服务器设置定义了几个变量 在.env中: FLASK_RUN_PORT=5000 WEB_1_PORT=80 WEB_2_PORT=8001 然后在docker compose.yml中: version: '3.8' x-common-variables: &shared_envvars FLASK_ENV: development FLASK_APP: mai

我真的不理解docker compose在环境变量文件方面的行为

我已经为运行2 flask应用程序的简单echo服务器设置定义了几个变量

.env
中:

FLASK_RUN_PORT=5000
WEB_1_PORT=80
WEB_2_PORT=8001
然后在
docker compose.yml中:

version: '3.8'

x-common-variables: &shared_envvars
  FLASK_ENV: development
  FLASK_APP: main.py
  FLASK_RUN_HOST: 0.0.0.0
  COMPOSE_PROJECT_NAME: DOCKER_ECHOES

x-volumes: &com_volumes
  - .:/project          # maps the current directory, e.g. project root that is gitted, to /proj in the container so we can live-reload

services:
  web_1:
    env_file: .env
    build:
      dockerfile: dockerfile_flask
      context: .
    ports:
      - "${WEB_1_PORT}:${FLASK_RUN_PORT}"       # flask runs on 5000 (default). docker-compose --env-file .env up loads whatever env vars specified & allows them to be used this way here.
    volumes: *com_volumes
    environment:
      <<: *shared_envvars   # DRY: defined common stuff in a shared section above, & use YAML merge language syntaxe to include that k-v mapping here. pretty neat.
      FLASK_NAME: web_1
  web_2:
    env_file: .env
    build:
      dockerfile: dockerfile_flask
      context: .
    ports:
      - "${WEB_2_PORT}:${FLASK_RUN_PORT}"       # flask by default runs on 5000 so keep it on container, and :8001 on host
    volumes: *com_volumes
    environment:
      <<: *shared_envvars
      FLASK_NAME: web_2
很明显,在这种情况下,文件中定义的EnvVar没有加载。我知道,根据文档,我正在使用的
environment:
部分覆盖了
env\u文件中加载的内容:
。但这些变量并不相同。无论如何,如果这是问题所在,那么第一种方法也不应该起作用,对吗


上面的错误是什么?

实际上,
env_文件
是在生成图像后加载的。我们可以核实这一点。通过上面我发布的代码,我可以看到
env_file.env
在构建时没有加载,因为我收到了错误消息(告诉我
WEB_PORT_1
没有设置等)

但这可能只是因为从未加载该文件。为了排除这种情况,我们构建映像(比如通过使用
docker compose build-e(…)
提供缺少的参数),然后我们可以确定它确实加载了(在我的例子中,通过在flask应用程序中记录它的值,或者简单的打印到屏幕等)

这意味着
env_file
的内容可用于正在运行的容器,但不能用于之前(例如在构建图像时)

如果在构建时在
docker compose.yml
文件中使用这些变量,则此文件必须命名为
.env
(除非有方法提供默认名称以外的名称,但如果是这样,我还没有找到任何名称)。这就是为什么将
env_文件:flask.env
更改为
env_文件:.env
似乎可以工作的原因-但它工作的真正原因是因为我的端口是在
.env
中指定的,具有docker compose无论如何都会解析的默认名称。它不在乎我是在
docker compose.yml
文件中指定的还是否t

总结如下:

  • 如果需要将环境变量提供给docker compose进行构建,则必须将它们存储在
    .env
    中。无需执行其他操作,只需确保此文件与
    docker compose.yml
    位于同一目录中。无法更改默认名称
    .env
  • 要在容器运行时提供envar,可以将它们放在
    foo.env
    中,然后指定
    env\u文件:foo.env
  • 对于运行时变量,另一个选项是指定它们
    environment:[vars]
    ,前提是可以在
    docker compose.yml
    中对它们进行硬编码。根据doc(未测试),这些变量将覆盖
    env_文件定义的任何变量

实际上,
env_文件
是在图像生成后加载的。我们可以验证这一点。通过我上面发布的代码,我可以看到
env_文件.env
在生成时没有加载,因为我收到了错误消息(告诉我
webport_1
未设置等)

但这可能只是因为从未加载该文件。为了排除这种情况,我们构建了该图像(比如通过使用
docker compose build-e(…)
提供缺少的参数),然后我们可以确定它确实加载了(在我的情况下,通过在flask应用程序中记录其值,或者简单地打印到屏幕等)

这意味着
env_file
的内容可用于正在运行的容器,但不能用于之前(例如在构建图像时)

如果在构建时在
docker compose.yml
文件中使用这些变量,则此文件必须命名为
.env
(除非有方法提供默认名称以外的名称,但如果是这样,我还没有找到任何名称)。这就是为什么将
env_文件:flask.env
更改为
env_文件:.env
似乎可以工作的原因-但它工作的真正原因是因为我的端口是在
.env
中指定的,具有docker compose无论如何都会解析的默认名称。它不在乎我是在
docker compose.yml
文件中指定的还是否t

总结如下:

  • 如果需要将环境变量提供给docker compose进行构建,则必须将它们存储在
    .env
    中。无需执行其他操作,只需确保此文件与
    docker compose.yml
    位于同一目录中。无法更改默认名称
    .env
  • 要在容器运行时提供envar,可以将它们放在
    foo.env
    中,然后指定
    env\u文件:foo.env
  • 对于运行时变量,另一个选项是指定它们
    environment:[vars]
    ,前提是可以在
    docker compose.yml
    中对它们进行硬编码。根据doc(未测试),这些变量将覆盖
    env_文件定义的任何变量

尝试
env_file
获得相同的结果。正如我所期望的,因为这两个都是有效的yaml符号…如果它能工作就好了,但它仍然无法解释为什么不能工作。我已经可以使它工作了(通过简单地命名我的文件.env)但我不想不知道潜在的问题…你没有做错任何事。检查是否有语法错误。事实证明确实没有语法错误。我的用法是错误的。所有这些都是关于何时加载的。使用相同的结果尝试
env_file
。正如我所预期的,因为两者都是有效的yaml符号…如果有工作正常,但它仍然无法解释为什么没有。我已经可以让它工作了(通过简单地命名我的文件.env),但我不喜欢不知道潜在的问题…你没有做错任何事。检查是否有语法错误。事实证明确实没有语法错误。我的用法是错误的。这都是关于何时加载它们。
(venv) [fv@fv-hpz420workstation flask_echo_docker]$ docker-compose up
WARNING: The WEB_1_PORT variable is not set. Defaulting to a blank string.
WARNING: The FLASK_RUN_PORT variable is not set. Defaulting to a blank string.
WARNING: The WEB_2_PORT variable is not set. Defaulting to a blank string.
ERROR: The Compose file './docker-compose.yml' is invalid because: