使 .env 文件中的 docker env 变量在构建步骤(Dockerfile)和容器中运行时可用

问题描述 投票:0回答:1

场地

给定一个文件

oneSourceOfTruth.env

FOO=42
... (many entries)

和一个

docker-compose.yml

services:
  my-service:
    dockefile: ./Dockerfile
    env_file: oneSourceOfTruth.env

🏁 目标

我希望通过

oneSourceOfTruth.env
 在构建步骤
中以及在运行时 (Dockerfile
) 期间在容器中使用 
docker compose build 中的所有变量。这些变量是“静态”的,因为它们一旦设置(在构建之前),然后对于特定构建和从构建生成的容器就不再更改。
不幸的是,它不适用于 
docker compose up 选项,因为它仅将环境变量传递给 containers

。环境变量在构建期间不可用(例如,在 Dockerfile 中使用

env_file

 命令)。
旁注
:我不一定需要直接访问 
RUN

文件本身内的环境变量,例如我们的

docker-compose.yml 文件中没有

有类似以下内容。
docker-compose.yml
⭕约束

args:
   - FOO=$FOO
文件相当长。出于可扩展性的原因和更好的代码质量,我想将此文件视为“事实的一个来源”,其中环境变量是

声明

设置

。也就是说,引入(删除)环境变量只意味着我必须在此文件中单独添加(删除)一行。
❎ 在不考虑约束的情况下解决目标的方法。 来自

对某个问题的评论

。使用

  • oneSourceOfTruth.env 在你的 Dockerfile 中。对每个变量都执行此操作。一位用户知道我对这种方法的感受(请参阅
  • 此处
):

如果您有一个很大的环境文件,那么这不是一个实用的解决方案。如果您只能读取从撰写文件传递的环境变量,这会使开发变得乏味且不必要的烦人。硬编码变量从来都不好,因为如果您想添加更多环境变量,则必须编辑多个文件。

here

ARG FOO ENV FOO $FOO
提出的解决方案对我不起作用(环境变量未填充/为空)。

按照

here

here
    所述,在
  • source oneSourceOfTruth.env && docker-compose build
    文件的
    environment
    部分传递环境变量。
    我查看过的其他答案:

docker-compose.yml

文件和。为了完整起见,这就是我想解决这个问题的原因;)

在我们的

env_file中,我们使用以下Rails命令来预编译我们的资产:

Dockerfile

不幸的是,这将产生整个 Rails 机制(至少我们可以避免使用
RUN DB_ADAPTER=nulldb bundle exec rails assets:precompile

适配器从
这里
连接到数据库)。存在一个选项

DB_ADAPTER=nulldb

,可以将其设置为 
initialize_on_precompile 以避免为此任务启动 Rails,请参阅此处
)。但是,此选项已从 Rails 代码库中删除,请参阅
此提交
这意味着我们也被迫在 false 任务中加载环境变量。如前所述,通过 precompile

文件中的关键

env_file

,环境变量仅在容器中可用,而不是在构建期间可用(我们需要它们来执行 
docker-compose.yml
 任务)。到目前为止的解决方法是在 ruby on Rails 代码中的任何地方使用 
precompile
,这样如果未指定,变量默认为 
ENV("Foo", nil)
。这样一切就可以了:在 
nil
 任务期间,所有环境变量都是 
precompile
 但我们并不需要它们来完成预编译资产的任务。在生产运行时,环境变量将可用。
但是通过这种方法,当我们真的忘记设置环境变量时,我们会默默地忽略这种情况。然后,同样在生产过程中,变量将为
nil
,我们只能通过它引起的影响来识别这一点。因此,到目前为止,我们的解决方案实际上只是一种解决方法,应该予以修复。如果变量不可用,它应该在项目的构建步骤期间引发 
nil

,而不仅仅是当用户抱怨我们的应用程序中的某些内容无法正常工作时。这可以通过使用

KeyError

 而不是 
ENV("Foo")
 来实现,但现在我们在 
ENV("Foo", nil)
 任务期间遇到关键错误,因为环境变量在 
precompile
 中不可用(我们在其中执行 
Dockerfile
 任务) 。这正是问题所在;)

您的机器上有可用的 
precompile

,Docker 构建发生在其中,对吗?
docker docker-compose dockerfile environment-variables
1个回答
0
投票
然后你可以这样做:

oneSourceOfTruth.env

请记住,最终的 Docker 镜像应该

包含任何秘密。因此,我建议在完成构建之前再次从图像文件中删除
# ...
WORKDIR /app
COPY oneSourceOfTruth.env /app/oneSourceOfTruth.env
RUN source /app/oneSourceOfTruth.env
RUN DB_ADAPTER=nulldb bundle exec rails assets:precompile
RUN rm -f /app/oneSourceOfTruth.env
# ...
,或者进行多阶段构建,在第一步中进行构建并将构建结果(不带

oneSourceOfTruth.env)复制到第二步构建步骤。

在运行时,像您已经做的那样在 Docker Compose 配置中传递 
oneSourceOfTruth.env

© www.soinside.com 2019 - 2024. All rights reserved.