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

Lee*_*fin 1 environment-variables docker docker-compose

在我的 docker-compose.yml 中,我定义了两个服务,app以及db.

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}
Run Code Online (Sandbox Code Playgroud)

正如你在上面看到的,我已经定义了两个 env 文件,app.envdb.env在和服务的env_file选项中。appdb

应用程序.env:

MY_PORT=8081
Run Code Online (Sandbox Code Playgroud)

db.env:

DB_PORT=4040
DB_URL=postgres://myapp:app@db:4040/myapp
Run Code Online (Sandbox Code Playgroud)

我想检查我的 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]
Run Code Online (Sandbox Code Playgroud)

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

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

And*_*zen 5

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

这很容易与提供.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 swarm 有不同的方法来帮助你解决这个问题。

这些是高度安全的解决方案,可以限制机密的操作员,并且开发人员或无权访问的操作员不会看到机密。

但是对于单节点 docker 主机,不是在 swarm 模式下运行(secrets 只在 swarm 模式下工作),真的没有很多花哨的选择。据我所知,您必须在构建和部署管道中手动管理它。

您的服务的敏感配置不应该与服务定义放在同一个存储库中,这是对的。诸如数据库的 root 密码或生产环境的服务发现服务的凭据之类的东西不需要与源相邻。

传统上,另一个存储库将包含此 - 让您有机会限制具有此访问权限的人群。构建/部署服务器/服务将检出您的服务的新版本,或许构建它,然后检出配置存储库并使用从那里的配置启动服务。并且,确保之后删除配置文件。

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

我希望这是有帮助的?