在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}
从上面可以看到,我在app.env
和db.env
服务的env_file
选项中定义了两个环境文件app
和db
。 / 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文件应如何正常用于不同的环境,例如开发,登台和生产环境?成像不同的环境对于这些变量具有不同的值。有人可以提供一些例子吗?
答案 0 :(得分:1)
此操作失败的原因是,您定义的外部变量app.env
和db.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.yml
文件中的变量扩展。.env
文件docker-compose.yml
文件中的环境变量扩展。如果将值迁移到单个.env
文件中,并将其与docker-compose.yml
文件放置在同一目录中,则此方法应该起作用。
据我了解的第二个问题,您正在询问应如何使用.env
文件或env_file
选项为您的不同环境配置服务。
我认为对此没有一个简单而单一的答案。它可以通过多种方式解决。但这还取决于您要部署到什么?是kubernetes吗? Docker群?还是只有一个节点的Docker主机?
Kubernetes和Docker群有不同的方法来帮助您解决这一问题。
这些是高度安全的解决方案,其中可以限制秘密操作员,并且秘密消息不会被没有访问权限的开发人员或操作员看到。
但是对于不是在集群模式下运行的单节点泊坞窗主机(秘密仅在集群模式下工作),确实没有很多不错的选择。据我所知,您将必须在构建中手动管理此问题并部署管道。
您很对,服务的敏感配置不应与服务定义位于同一存储库中。数据库的root密码或生产环境的服务发现服务的凭据之类的内容无需位于源旁边。
传统上,另一个存储库将包含此存储库-给您机会限制具有此访问权限的人群。构建/部署服务器/服务将签出您的服务的新修订版,也许会对其进行构建,然后签出配置存储库,并从那里开始使用配置进行服务。并且,请确保随后删除配置文件。
对于单个节点docker主机部署方案,这将是我推荐的解决方案-两个存储库,以及一些脚本,这些脚本可确保在部署期间放置正确的.env文件,然后再次将其删除。
我希望这对您有帮助吗?