繁体   English   中英

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

[英]Why does variables substitution not work when using multiple env_files in docker-compose.yml?

我正在尝试使用多个.env文件来获取.env -compose文件,而且我没有运气。 我正在尝试设置三个.env文件:

  • 所有容器实例中的全局设置相同
  • 特定于环境的设置(仅用于测试或开发的东西)
  • 本地设置 - 开发人员可能需要更改的可覆盖的东西,以防它们与端口号发生冲突

docker-compose.yml文件如下所示:

version: '2'
services:
  db:
    env_file:
      - ./.env
      - ./.env.${ENV}
      - ./.env.local
    image: postgres
    ports:
      - ${POSTGRES_PORT}:5432

.env看起来像这样:

POSTGRES_USER=myapp

.env.development看起来像这样:

POSTGRES_PASSWORD=supersecretpassword
POSTGRES_HOST=localhost
POSTGRES_PORT=25432
POSTGRES_DB=myapp_development

在这种情况下,不存在.env.local

运行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]

从该错误消息,看起来我的环境变量都没有被使用。 我刚刚升级到最新的可用docker-compose - 同样的错误:

$ docker-compose --version
docker-compose version 1.8.0-rc1, build 9bf6bc6

这里有什么想法? 拥有一个可以跨多个环境工作docker-compose.yml会很不错。

请记住,您有两种不同的环境来定义变量。 执行docker-compose命令的主机和容器本身(在您的情况下运行db服务)。

docker-compose.yml文件可以访问主机的环境变量。 因此ENV可以从.env docker-compose命令访问,但不能在.env文件中访问。

相反, ENV的值在容器内是不可达的,但.env文件中定义的所有变量.env

我不知道你是否真的需要你的db容器来访问.env.development定义的变量。 但至少看起来你的主机需要拥有该文件的内容,所以当调用docker-compose命令时,会定义POSTGRES_PORT变量。

要修复您的特定问题,您还需要在主机上定义环境变量,而不仅仅是容器。 你可以这样做:

#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.

希望有所帮助。

为了根据运行环境应用不同的/多个env_files,例如开发/登台/制作,我认为docker-compose更好的方法是使用多个docker-compose yml文件。

例如:

1.从定义服务的规范配置的基本文件开始。

docker-compose.yml

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

2.添加用于开发的覆盖文件,顾名思义,可以包含现有服务或全新服务的配置覆盖。

泊坞窗,compose.override.yml

web:
  build: .
  volumes:
    - '.:/code'
  ports:
    - 8883:80
  env_file:
    - .env.dev

当你运行docker-compose up它会自动读取覆盖。

3.为生产环境创建另一个覆盖文件。

泊坞窗,compose.prod.yml

web:
  ports:
    - 80:80
  env_file:
    - .env.prod

要使用此生产Compose文件进行部署,您可以运行

docker-compose -f docker-compose.yml -f docker-compose.prod.yml up

注意

我的Docker版本:

$ docker -v
Docker version 18.06.1-ce, build e68fc7a

$ docker-compose -v
docker-compose version 1.22.0, build f46880fe

参考: https//docs.docker.com/compose/extends/

阅读本页时: https//docs.docker.com/compose/environment-variables/

根据我的理解,你应该做以下事情:

对于全局变量(不应该更改)创建一个像这样的env文件:

VAR1=VALUE1
VAR2=VALUE2

对于其他人(可能会改变),你应该在docker-compose.yml的环境下添加他们的名字,如下所示:

environment:
    - VAR1
    - VAR2

这将从正在运行docker-compose的shell中获取VAR1和VAR2值。

我希望这有帮助。

关于.env文件和docker-compose.yml中的env_file选项存在误解,因为它非常模糊。 Shin在github问题中非常好地指出它docker-compose不使用env_file 我将引用他的总结:

  • docker-compose.yml文件中的变量替换将从shell的环境和.env文件中提取(按优先级降序排列)。

  • 容器中可用的变量是env_file文件中找到的值和服务的环境部分中描述的值的组合。

  • 这是两组完全独立的功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM