Dotenvx如何处理.env文件变量和环境变量的冲突?
· 3 min read
我们都知道.env
文件中的变量通常会加载到环境变量中,但是有一些例外,如Java,dotenv-java不会覆盖环境变量,主要是Java不允许覆盖环境变量。
但是对于大多数语言来说,.env
文件中的变量会融合到环境变量中,如果环境变量中已经存在同名变量,那么该如何处理呢?
目前主流的做法采取的是环境变量优先原则,也就是如果环境变量中已经存在同名变量,那么.env
文件中的变量将被忽略,除非你在加载.env
文件时,
明确指定覆盖环境变量,如Python的python-dotenv
库,提供了override
参数,设置为True
即可覆盖环境变量。
Dotenvx的逻辑也是这样的,只是在加载.env
文件后会进行对应的解密操作,然后再将解密后的变量加载到环境变量中,如果遇到同样的变量名,
那么dotenvx变量会覆盖环境变量,采用的是dotenvx优先原则,而非环境变量优先原则。
这样设计的目的主要有几个考量因素:
- 加密优先:dotenvx主要的目的是包含敏感信息,而环境变量中的值通常都是明文的,原则来说,保密的数据应该优先于明文数据。
- 一致性:如果你使用
.env
文件来存储配置,从排查问题的角度来说,你还是首先会从.env
文件中查找配置项,而不是环境变量。 如果是环境变量,你还是需要登录服务器进行排查,增加了排查的复杂度。一些容器场景,还需要访问特定的运维系统才能看到,无意增加了成本。 - 更高的安全性:如果环境变量优先的话,你完全可以通过设置环境变量来覆盖
.env
文件中的敏感信息,如收款或者捐款账号,如果一些恶意的人调整了服务器的环境变量进行覆盖,那么就可能导致资金损失。 - 防篡改:Dotenvx提供了一个签名机制,其目的是防止
.env
文件被篡改,也就是没有人能够看到.env
文件中的敏感信息,但是我也不希望有人能够篡改这些信息,毕竟公钥就写在.env
文件中,任何人都可以使用该公钥再加密一个变量,或者覆盖原来的变量,就破坏了dotenvx的签名特性。
基于以上的种种考量,dotenvx采用了dotenvx优先原则,也就是.env
文件中的变量会覆盖环境变量。在一些场景中,这个可能会带来一些不便,如想通过环境变量调整配置项,
这种情况下,你可能需要创建不同的profile,来区分不同的环境配置,如.env.ab
,.env.v_1
这样的文件,来区分不同的环境配置。
dotenvx这种做法,保证了配置的安全第一的特性,配置的一致性,以及防篡改的特性,也避免了歧义,那么就Dotenvx First吧。