docker-compose env_file仅加载.env,但未加载特定名称 [英] docker-compose env_file only loading .env, but not a specific name
问题描述
关于环境变量文件,我真的不了解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 thedocker-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 specifyenv_file:foo.env
. - For run-time variable, another option is to specify them
environment: [vars]
, if just hard-coding them in thedocker-compose.yml
is acceptable.. According to doc (not tested) those will override any variables also defined by theenv_file
这篇关于docker-compose env_file仅加载.env,但未加载特定名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!