简体   繁体   English

为什么在docker-compose.yml中使用多个env_files时变量替换不起作用?

[英]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文件:

  • global settings that are the same across all container instances 所有容器实例中的全局设置相同
  • environment-specific settings (stuff just for test or dev) 特定于环境的设置(仅用于测试或开发的东西)
  • local settings - overridable things that a developer might need to change in case they have conflicts with, say, a port number 本地设置 - 开发人员可能需要更改的可覆盖的东西,以防它们与端口号发生冲突

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: 例如:

1. Start with a base file that defines the canonical configuration for the services. 1.从定义服务的规范配置的基本文件开始。

docker-compose.yml

web:
  image: example/my_web_app:latest
  env_file:
    - .env

2. Add the override file for development, as its name implies, can contain configuration overrides for existing services or entirely new services. 2.添加用于开发的覆盖文件,顾名思义,可以包含现有服务或全新服务的配置覆盖。

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它会自动读取覆盖。

3. Create another override file for the production environment. 3.为生产环境创建另一个覆盖文件。

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

Note 注意

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.

相关问题 在 docker-compose.yml 的 env_files 中使用系统环境变量 - Use system environment variables in env_files in docker-compose.yml 如何使用环境变量用一个 docker-compose.yml 部署多个数据库? - How to deploy multiple databases with one docker-compose.yml using env variables? 容器在使用 Dockerfile 时工作,但在使用 docker-compose.yml 时不工作 - Container works when using Dockerfile, but does not work when using docker-compose.yml 来自docker-compose.yml入口点的env fiile的环境变量 - Environment variables from env fiile in entrypoint in docker-compose.yml 扩展具有多个实例的服务时 docker-compose.yml 中的命令替换 - Command substitution in docker-compose.yml when scaling a service with multiple instances 未使用docker-compose.yml在Docker容器中设置环境变量 - Environment variables are not set in docker container using docker-compose.yml 使用sudo运行docker-compose时docker-compose.yml文件中的变量替换 - Variable substitution in docker-compose.yml file when running docker-compose with sudo 我可以在 docker-compose.yml 文件中设置/获取变量吗? - Can I set/get variables in docker-compose.yml files? 在 docker-compose.yml 中重用环境变量 - Re-using environment variables in docker-compose.yml 从 .env 或 dockerFile/docker-compose.yml 获取环境变量,到 config,php 以连接到 mysql 数据库 - Get env variables from .env or dockerFile/docker-compose.yml, to config,php to connect to mysql database
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM