dotenv 是不是与十二要素应用程序相矛盾?
Posted
技术标签:
【中文标题】dotenv 是不是与十二要素应用程序相矛盾?【英文标题】:Does dotenv contradict the Twelve-Factor App?dotenv 是否与十二要素应用程序相矛盾? 【发布时间】:2017-09-12 16:13:11 【问题描述】:我已经阅读了有关Twelve Factor App's Config - Section III 的信息,并在 NodeJS 中寻找了一种方法。似乎大多数人推荐dotenv 将配置存储在环境变量中。
但是,dotenv 似乎与十二要素应用程序相矛盾,如下所述:
另一种配置方法是使用未检入修订控制的配置文件,例如 Rails 中的 config/database.yml。与使用检入代码仓库的常量相比,这是一个巨大的改进,但仍然存在弱点:很容易将配置文件错误地检入代码仓库;配置文件倾向于分散在不同的地方和不同的格式,使得在一个地方查看和管理所有配置变得困难。此外,这些格式往往是特定于语言或框架的。
十二因素应用程序将配置存储在环境变量中(通常缩写为 env vars 或 env)。环境变量很容易在部署之间更改,而无需更改任何代码;与配置文件不同,它们被意外签入代码仓库的可能性很小;与自定义配置文件或其他配置机制(如 Java 系统属性)不同,它们是与语言和操作系统无关的标准。
理解这句话,似乎使用 dotenv,您将创建一个配置文件 .env
,然后将它们导出为环境变量。
这不会违反十二要素应用程序吗,因为.env
文件可能会被意外签入代码仓库?
【问题讨论】:
技术说明:.env
文件不会以任何方式导出环境变量,有些库只是让您使用.env
文件来扩展process.env
,而无需设置虚拟环境或放置不在容器/VM 中工作时,全局环境中仅与此应用相关的值
【参考方案1】:
OP 提出了一个深思熟虑的问题。
我会说 dotenv 与第 3 节的 12 因素相矛盾,原因有两个。
根据定义,即本段:“配置的另一种方法是使用未签入修订控制的配置文件,......仍然有缺点:很容易错误地将配置文件签入到repo; ...(因此 12 因素应用程序使用不同的方法)将配置存储在环境变量中”,现在你看到了,只是因为 .env
文件可以/应该在 .gitignore
中声明, 并不能使 dotenv 免于“容易错误地将配置文件签入 repo”的审查。
如果一个应用从 且仅从 env var 读取配置,则该应用可能完全符合 12 因素第 3 节。但是一个 dotenv 功能是允许应用程序自动拾取./.env
(如果可用)。从这个意义上说,.env
文件——尽管它具有欺骗性的名称——是一个配置文件,彻头彻尾。同样,这属于 12 因素明确避免的配置方法类别。
话虽如此,dotenv 仍然是可行的选择之一。其他选项包括:在 docker 层管理环境变量;或在 unix 用户的 .*rc
文件中;或在网络服务器配置中;或/etc/profile
(引自this another SO post)。 dotenv
提供了一种最通用的文件格式(fwiw,docker env_file 也同样简单,尽管它们的规格不同),但是 dotenv
是唯一一种“污染”目标应用程序代码库的解决方案。
底线,dotenv
很好,有趣的是许多dotenv
实现继承了它从 12 因素应用程序原则开始的声明,但只有少数人承认其 .env
方法偏离了 12-因素应用程序。
【讨论】:
【参考方案2】:在有人实际提交并推送.env
之前,不会违反 12 因素;)
.env
文件也可以存储在 repo 本身之外,因为库或应用程序仍然必须读取 .env
文件并将变量推送到环境中。根据您的实现,这可以像将路径从 ".env"
更改为 "../.env"
一样简单。
使用.env
文件可能是一个很好的折衷方案,可以让开发人员轻松管理环境,但在部署期间仍与更好的环境实践兼容。我可能有 30-40 个 12 因素风格的应用程序在虚拟机中运行,如果没有像 .env
这样的“垫片”,必须单独管理每个环境是令人生畏的。
【讨论】:
【参考方案3】:大多数版本控制系统都有忽略某些文件的方法。
Git 有 .gitignore
SVN 有"Special Ignores"
附带说明,这些技术同样用于忽略node_modules
目录,以避免不必要地复制文件。
【讨论】:
以上是关于dotenv 是不是与十二要素应用程序相矛盾?的主要内容,如果未能解决你的问题,请参考以下文章