使用 ENV 变量是个好主意吗?

Is using ENV variables a good idea?

背景

我们的应用程序使用 MySQL 数据库和更多服务。

为了将我们的应用程序连接到这些服务器,我们将用户名和密码保存在 prod.config 文件中。如果我们在开发中,我们使用 dev.config 文件等等...

最近,我一直在研究行业中的良好实践(例如 https://12factor.net/),其中大多数(如果不是全部)指定用户名和密码等信息来连接到数据库和其他服务不应在配置文件中,而应在 ENV 变量中。

如果您不知道什么是 12 因子规格,可以查看此免费教程:

问题

现在,乍一看这看起来不错。许多 CI 工具,如 Travis 或 CircleCI 已经强制你这样做了。这里的问题是当您最小的应用程序使用多种服务时。

在我们的例子中,对于我们最小的应用程序,我们需要 13 个 ENV 变量。不会在任何特定文件中的变量,它们都必须在它们 运行 所在的机器的 ENV 中。

我看不出这怎么能被视为一种好的做法。我理解不将所有这些敏感数据推送到配置文件的主要想法,但这种方法会带来几个问题:

  1. 当机器重新启动时,您将丢失所有 ENV 变量。
  2. 如果你想避免前面的问题,你需要在机器启动时 运行 一个脚本来设置这些变量,这意味着你会将它们存储在一个文件中,从而破坏了整个目的。
  3. 你把这些变量保存在哪里?他们需要在别处,而不是你脆弱的脑袋!

问题

我要退后一步,向您提出一个问题:您为什么要尝试从测试环境连接到生产数据库?

CI 工具的美妙之处在于它们允许您启动 Docker 容器以充当测试服务。在您的生产代码中,将密码保存在环境变量中被认为是最佳实践,主要原因有两个: 1.) 如果有人得到了你的代码,他们就可以访问你的数据库。它需要额外的安全级别,这是不现实的。 2.) 如果有人确实 得到了您的密码,您希望能够快速更改它们。如果您的代码引用环境变量而不是硬编码字符串,这会更容易做到。

当您迁移到 CI 系统时,第 2 点变得没有实际意义,但第 1 点变得非常重要。使用 Travis 和 CircleCI,您的配置文件是 public。如果你将你的生产密码放入你的配置文件,我(或更恶意的人)可以扫描你的文件并跳转到你的数据库。我听说过黑客为配置文件中的硬编码密码抓取 public 存储库的故事。使用像 CircleCI.

这样的工具会更容易

您在 Travis 和 CircleCI 中设置的环境变量应该存储在存储库级别 - 您不需要移动或保存变量。

生产系统中的环境变量应设置为启动脚本的一部分。这在很大程度上取决于您使用的是哪种服务,因此我不会在这里详细介绍。