[英]Why does variables substitution not work when using multiple env_files in docker-compose.yml?
I'm trying to get a docker-compose file working with multiple .env
files, and I'm not having any luck. 我正在尝试使用多个
.env
文件来获取.env
-compose文件,而且我没有运气。 I'm trying to setup three .env
files: 我正在尝试设置三个
.env
文件:
My docker-compose.yml
file looks like this: 我
docker-compose.yml
文件如下所示:
version: '2'
services:
db:
env_file:
- ./.env
- ./.env.${ENV}
- ./.env.local
image: postgres
ports:
- ${POSTGRES_PORT}:5432
.env
looks like this: .env
看起来像这样:
POSTGRES_USER=myapp
and the .env.development
looks like this: 而
.env.development
看起来像这样:
POSTGRES_PASSWORD=supersecretpassword
POSTGRES_HOST=localhost
POSTGRES_PORT=25432
POSTGRES_DB=myapp_development
.env.local
doesn't exist in this case. 在这种情况下,不存在
.env.local
。
After running ENV=development docker-compose up
, I receive the following output: 运行
ENV=development docker-compose up
,我收到以下输出:
$ ENV=development docker-compose up
WARNING: The POSTGRES_PASSWORD variable is not set. Defaulting to a blank string.
WARNING: The POSTGRES_DB variable is not set. Defaulting to a blank string.
WARNING: The POSTGRES_PORT variable is not set. Defaulting to a blank string.
ERROR: The Compose file './docker-compose.yml' is invalid because:
services.db.ports is invalid: Invalid port ":5432", should be [[remote_ip:]remote_port[-remote_port]:]port[/protocol]
From that error message, it looks like none of my environment variables are being used. 从该错误消息,看起来我的环境变量都没有被使用。 I just upgraded to the newest available docker-compose as well - same errors:
我刚刚升级到最新的可用docker-compose - 同样的错误:
$ docker-compose --version
docker-compose version 1.8.0-rc1, build 9bf6bc6
Any ideas here? 这里有什么想法? Would be nice to have a single
docker-compose.yml
that would work across multiple environments. 拥有一个可以跨多个环境工作
docker-compose.yml
会很不错。
Keep in mind that there are 2 different environments where you are defining variables. 请记住,您有两种不同的环境来定义变量。 The host machine where you are executing the docker-compose command, and the container itself (running the db service in your case).
执行docker-compose命令的主机和容器本身(在您的情况下运行db服务)。
Your docker-compose.yml
file has access to your host's environment variables. 您
docker-compose.yml
文件可以访问主机的环境变量。 Hence ENV
is reachable from the docker-compose
command, but not these in your .env
files. 因此
ENV
可以从.env
docker-compose
命令访问,但不能在.env
文件中访问。
On the contrary, the value for ENV
is not reachable inside the container, but all variables defined in your .env
files will. 相反,
ENV
的值在容器内是不可达的,但.env
文件中定义的所有变量.env
。
I don't know if you really need your db
container to access the variables defined on your .env.development
. 我不知道你是否真的需要你的
db
容器来访问.env.development
定义的变量。 But at least seem that your host machine needs to have the content of that file, so when the docker-compose command is called, the POSTGRES_PORT
variable is defined. 但至少看起来你的主机需要拥有该文件的内容,所以当调用docker-compose命令时,会定义
POSTGRES_PORT
变量。
To fix your specific problem you would need to define the environment variables on your host machine too, not only for the container. 要修复您的特定问题,您还需要在主机上定义环境变量,而不仅仅是容器。 You could do something like this:
你可以这样做:
#Set for host
ENV=development
#Also sets the variables on the host
source ./.env.$ENV
#POSTGRES_PORT defined in .env.development is used here
docker-compose up
#since env_file also contains .env.development, the variables will be reachable from the container.
Hope that helps. 希望有所帮助。
In order to apply different/multiple env_files depending on the running environment, such as development/staging/production, I think a better way for docker-compose is to use multiple docker-compose yml files. 为了根据运行环境应用不同的/多个env_files,例如开发/登台/制作,我认为docker-compose更好的方法是使用多个docker-compose yml文件。
For example: 例如:
docker-compose.yml
web:
image: example/my_web_app:latest
env_file:
- .env
docker-compose.override.yml 泊坞窗,compose.override.yml
web:
build: .
volumes:
- '.:/code'
ports:
- 8883:80
env_file:
- .env.dev
When you run docker-compose up
it reads the overrides automatically. 当你运行
docker-compose up
它会自动读取覆盖。
docker-compose.prod.yml 泊坞窗,compose.prod.yml
web:
ports:
- 80:80
env_file:
- .env.prod
To deploy with this production Compose file you can run 要使用此生产Compose文件进行部署,您可以运行
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up
My Docker version: 我的Docker版本:
$ docker -v
Docker version 18.06.1-ce, build e68fc7a
$ docker-compose -v
docker-compose version 1.22.0, build f46880fe
Reference: https://docs.docker.com/compose/extends/ 参考: https : //docs.docker.com/compose/extends/
while reading this page: https://docs.docker.com/compose/environment-variables/ 阅读本页时: https : //docs.docker.com/compose/environment-variables/
and from my understanding, you should do the following: 根据我的理解,你应该做以下事情:
for the global variables(that should not change) make an env file like so: 对于全局变量(不应该更改)创建一个像这样的env文件:
VAR1=VALUE1
VAR2=VALUE2
and for the others(that might change) you should add their name under environment in docker-compose.yml like this: 对于其他人(可能会改变),你应该在docker-compose.yml的环境下添加他们的名字,如下所示:
environment:
- VAR1
- VAR2
this will take the VAR1 and VAR2 values from the shell you are running docker-compose. 这将从正在运行docker-compose的shell中获取VAR1和VAR2值。
I hope this helps. 我希望这有帮助。
There is a misconception regarding the .env file and the env_file option in the docker-compose.yml, as it is very ambiguous. 关于.env文件和docker-compose.yml中的env_file选项存在误解,因为它非常模糊。 Shin points it out very nicely in the github issue docker-compose doesn't use env_file .
Shin在github问题中非常好地指出它docker-compose不使用env_file 。 I will just quote his summary:
我将引用他的总结:
Variable substitution in your docker-compose.yml file will be pulled (in decreasing order of priority) from your shell's environment and your .env file.
docker-compose.yml文件中的变量替换将从shell的环境和.env文件中提取(按优先级降序排列)。
Variables available in your container are a combination of values found in your env_file files and values described in the environment section of the service.
容器中可用的变量是env_file文件中找到的值和服务的环境部分中描述的值的组合。
Those are two entirely separate sets of features.
这是两组完全独立的功能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.