无法从env_file中声明的文件读取环境变量

时间:2020-06-22 16:19:27

标签: docker docker-compose environment-variables

在docker-compose.yml中,我定义了两个服务appdb

version: "3.7"

services:
  app:
    image: my_app
    container_name: my-app
    ports:
      - ${MY_PORT}:${MY_PORT}
    env_file:
      - ./app.env
    ...
    depends_on:
      - db
    environment:
      - DATABASE_URL=${DB_URL}
  db:
    image: my_db
    container_name: my-db
    env_file:
      - ./db.env
    ports:
      - ${DB_PORT}:${DB_PORT}

从上面可以看到,我在app.envdb.env服务的env_file选项中定义了两个环境文件appdb。 / p>

app.env:

MY_PORT=8081

db.env:

DB_PORT=4040
DB_URL=postgres://myapp:app@db:4040/myapp

我想检查我的docker-compose是否可以成功读取环境变量。因此,我运行命令docker-compose config。但是输出是

$ docker-compose config
WARNING: The MY_PORT variable is not set. Defaulting to a blank string.
WARNING: The DB_URL variable is not set. Defaulting to a blank string.
WARNING: The DB_PORT variable is not set. Defaulting to a blank string.
ERROR: The Compose file './docker-compose.yml' is invalid because:
services.app.ports is invalid: Invalid port ":", should be [[remote_ip:]remote_port[-remote_port]:]port[/protocol]
services.db.ports is invalid: Invalid port ":", should be [[remote_ip:]remote_port[-remote_port]:]port[/protocol]

为什么我的docker compose无法从我在docker-compose.yml中的env_file选项中声明的那些env文件中读取环境变量?

此外,我还有另一个问题,那就是我知道通常不应该对环境文件进行版本控制,因为它可能包含凭据。 env文件应如何正常用于不同的环境,例如开发,登台和生产环境?成像不同的环境对于这些变量具有不同的值。有人可以提供一些例子吗?

1 个答案:

答案 0 :(得分:1)

此操作失败的原因是,您定义的外部变量app.envdb.env文件并在env_file选项中指定的环境变量仅被设置在启动的容器内-由docker-compose解析时不用于docker-compose.yml文件内的变量扩展。

这很容易与在.env文件所在的位置提供名为docker-compose.yml的文件的选项混淆。由于docker-compose将在.env文件(或您通过docker-compose.yml开关指定的文件旁边)旁边寻找一个名为-f的文件-并使用环境变量在解析之前先在该文件中进行docker-compose.yml文件中的变量扩展。

换句话说:

env_file选项

  • 将在容器内设置环境变量只是一项便利功能,可让您从docker-compose.yml文件中外部化环境变量
  • 在由docker-compose解析之前,这些文件中的
  • 环境变量将用于docker-compose.yml文件中的变量扩展。

.env文件

  • 在解析之前将用于docker-compose.yml文件中的环境变量扩展。
  • 不会在启动的容器内设置环境变量。

第一个问题的建议解决方案

如果将值迁移到单个.env文件中,并将其与docker-compose.yml文件放置在同一目录中,则此方法应该起作用。

第二个问题

据我了解的第二个问题,您正在询问应如何使用.env文件或env_file选项为您的不同环境配置服务。

我认为对此没有一个简单而单一的答案。它可以通过多种方式解决。但这还取决于您要部署到什么?是kubernetes吗? Docker群?还是只有一个节点的Docker主机?

Kubernetes和Docker群有不同的方法来帮助您解决这一问题。

这些是高度安全的解决方案,其中可以限制秘密操作员,并且秘密消息不会被没有访问权限的开发人员或操作员看到。

但是对于不是在集群模式下运行的单节点泊坞窗主机(秘密仅在集群模式下工作),确实没有很多不错的选择。据我所知,您将必须在构建中手动管理此问题并部署管道。

您很对,服务的敏感配置不应与服务定义位于同一存储库中。数据库的root密码或生产环境的服务发现服务的凭据之类的内容无需位于源旁边。

传统上,另一个存储库将包含此存储库-给您机会限制具有此访问权限的人群。构建/部署服务器/服务将签出您的服务的新修订版,也许会对其进行构建,然后签出配置存储库,并从那里开始使用配置进行服务。并且,请确保随后删除配置文件。

对于单个节点docker主机部署方案,这将是我推荐的解决方案-两个存储库,以及一些脚本,这些脚本可确保在部署期间放置正确的.env文件,然后再次将其删除。

我希望这对您有帮助吗?