docker-compose env_file仅加载.env,但未加载特定名称 [英] docker-compose env_file only loading .env, but not a specific name

查看:200
本文介绍了docker-compose env_file仅加载.env,但未加载特定名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于环境变量文件,我真的不了解docker-compose的行为.

I don't really make sense of docker-compose's behavior with regards to environment variables files.

我为运行2瓶应用程序的简单回显服务器设置定义了一些变量.

I've defined a few variables for an simple echo server setup with 2 flask application running.

.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

如果我使用上述命令运行 docker-compose up ,那么一切都会按预期进行.

If I run docker-compose up with the above, everything works as expected.

但是,如果我只是简单地将文件 .env 的名称更改为例如 flask.env ,然后相应地更改两个 env_file:.env env_file:flask.env ,然后我得到:

However, if I simply change the name of the file .env for, say, flask.env, and then accordingly change both env_file: .env to env_file: flask.env, then I get:

(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:

显然,在这种情况下,文件中定义的envvars没有被加载.我知道根据文档,我正在使用的 environement:部分会覆盖 env_file:中加载的内容.但是这些不是相同的变量.无论如何,如果那是问题所在,那么它也不应该以第一种方式起作用,对吗?

So obviously the envvars defined in the file were not loaded in that case. I know that according to the documentation, the section environement:, which I am using, overrides what is loaded in the env_file:. But those aren't the same variables. And at any rate, if that was the issue, it shouldn't work either with the first way, right?

上面有什么问题?

推荐答案

实际上,在构建图像之后,会加载 env_file .我们可以验证这一点.使用上面发布的代码,我可以看到在构建时尚未加载 env_file.env ,因为我收到了错误消息(告诉我 WEB_PORT_1 是未设置等.

Actually, the env_file is loaded AFTER the images have been built. We can verify this. With the code I have posted above, I can see that env_file.env has not been loaded at build time, because of the error message that I get (telling me WEB_PORT_1 is not set etc.).

但这可能仅仅是因为文件从未加载过.为了排除这种情况,我们构建映像(例如,通过为缺少的参数提供 docker-compose build -e(...),然后我们就可以确定确实已加载该映像(通过记录其值)在我的情况下是在烧瓶应用程序中,还是在屏幕上进行简单打印等).

But this could simply be that the file is never loaded. To rule that out, we build the image (say by providing the missing arguments with docker-compose build -e (...), then we can very that it is indeed loaded (by logging its value in the flask application in my case, or a simple print to screen etc.).

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

This means the the content of env_file is available to the running container, but not before (such as when building the image).

如果要在构建时在 docker-compose.yml 文件中使用这些变量,则该文件必须命名为 .env (除非有一种方法可以提供除默认名称外的其他名称,但如果有,则找不到任何名称).这就是为什么将 env_file:flask.env 更改为 env_file:.env SEEMED使其起作用的原因-但后来起作用的真正原因是因为我的端口是在 .env 具有docker-compose仍会解析的默认名称.不在乎我是否在 docker-compose.yml 文件中指定它.

If those variables are to be used within the docker-compose.yml file at BUILD time this file MUST be named .env (unless there is a way to provide a name other than the default, but if so I haven't found any). This is why changing env_file: flask.env to env_file: .env SEEMED to make it work - but the real reason why it worked then was because my ports were specified in a .env with the default name that docker-compose parses anyways. It didn't care that I specified it in docker-compose.yml file or not.

总结:

  • 如果需要在构建时将环境变量提供给docker-compose,则必须将它们存储在 .env 中.除了确保此文件与 docker-compose.yml 位于同一目录外,无需其他操作.您不能更改默认名称 .env
  • 要在容器运行时提供envar,可以将其放入 foo.env 中,然后指定 env_file:foo.env .
  • 对于运行时变量,另一种选择是在 environment:[vars] 中指定它们,如果只接受在 docker-compose.yml 中对其进行硬编码的话..根据文档(未经测试),这些变量将覆盖由 env_file
  • 定义的所有变量
  • If you need to feed environment variables to docker-compose for build-time, you must store them in a .env. No further actions needed, other than ensure this file is in the same directory as the docker-compose.yml. You can't change the default name .env
  • To provide envars at container run-time, you can put them in foo.env and then specify env_file:foo.env.
  • For run-time variable, another option is to specify them environment: [vars], if just hard-coding them in the docker-compose.yml is acceptable.. According to doc (not tested) those will override any variables also defined by the env_file

这篇关于docker-compose env_file仅加载.env,但未加载特定名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆