TL;博士
如何在两个生产和暂存 Rails 应用程序中使用production.yml.enc
和staging.yml.enc
凭据文件,而该应用程序只有常规的development
、test
和production
环境?
我正在使用 Heroku 并在这个问题中引用它。然而,这并不是特定于该供应商的。
详细地
一个应用程序通常会多次部署。一个实例用作生产,而另一个实例是暂存应用,预计将投入生产。Rails 促进了这种模式,因为创建新环境很容易。
但是,Heroku建议不要这样做,这是有充分理由的。例如,人们可能会想在这里和那里放一些if Rails.env.production?
,为一些"但它在分期中有效!?"周五晚上。最好有一个单一的生产环境,使用不同的参数集来实际区分阶段(例如,不同的 AWS S3 存储桶名称、不同的 API 密钥等(。为了实现这一目标,Heroku的建议是依靠环境变量。
从 Rails 5.2 及更高版本的 Rails 6 开始,凭据可以通过config/credentials
中的加密 Yaml 文件方便地处理。这通常是人们想要存储从一个环境到另一个环境变化的所有这些变量的地方,而不是使用混乱的环境变量。此机制可以在 Heroku 中使用,这要归功于包含用于解密凭证文件的密钥的单个RAILS_MASTER_KEY
环境变量。
但是这些作品不太合适。我们如何拥有单个production
环境,而凭据文件是每个环境的?
这可以通过暂存凭证文件和密钥以及基于环境变量的application.rb
开关来实现:
-
使用
EDITOR=vi rails credentials:edit --environment staging
创建并填充暂存凭证文件和密钥。 -
在
application.rb
中,添加:# Introduce the environment variable RAILS_CREDENTIALS_ENVIRONMENT to specify a custom # environment name of which to use the credentials file. Specifically aimed to use in staging, # where the environment is set to "production", but we need to use the "staging" environment variables. # This environment variable is also used to select the corresponding key file or -if that does not exist- # the corresponding environment variable. if ENV['RAILS_CREDENTIALS_ENVIRONMENT'].present? new_filename_no_ext = Rails.root.join 'config', 'credentials', ENV['RAILS_CREDENTIALS_ENVIRONMENT'] config.credentials.content_path = "#{new_filename_no_ext}.yml.enc" if File.exist? "#{new_filename_no_ext}.key" config.credentials.key_path = "#{new_filename_no_ext}.key" end end
-
将环境变量
:RAILS_CREDENTIALS_ENVIRONMENT
设置为production
或staging
,具体取决于具体情况。例如,Heroku 这样做heroku config:set -a theapp-staging RAILS_CREDENTIALS_ENVIRONMENT=staging
-
如果在暂存或生产中,您希望将密钥存储在环境变量而不是密钥文件中,则只需将密钥分配给
RAILS_MASTER_KEY
环境变量即可。如前所述,这优先于存储在文件中的键。请注意,在开发计算机上,您不希望设置RAILS_MASTER_KEY
,否则所有环境的凭据文件仍会获得相同的密钥,因此需要访问(例如(仅开发凭据的每个人都可以访问。
在源代码存储库中的每个环境中都有一个文件,或者本地服务器磁盘,工作,但您将有几个具有硬编码值的文件。
但是,如果您期望多个团队对单个应用程序有多个要求,您将需要多个开发和测试环境,以便保持一个完全负责其服务的独立团队:
- 发展
- 发布/部署
- 运维(非平台/系统管理(
管理方法是:在称为以下的平台上外部化您的配置: 配置管理器
此平台必须具有以下功能:
- 通过应用程序创建密钥对。喜欢 heroku 网络仪表板
- 公开 HTTP 终结点以从远程应用获取此变量
- 安全
您的 rails 应用程序必须在启动阶段获取变量,如果您的语言支持热重载变量,则必须立即获取变量。
这里有一些配置管理器:
- 动物园管理员 : http://www.therore.net/java/2015/05/03/distributed-configuration-with-zookeeper-curator-and-spring-cloud-config.html
- 领事 : https://www.consul.io
- 春云:https://www.baeldung.com/spring-cloud-configuration
- 配置网: https://github.com/software-architect-tools/confignet
使用这种方法,您将拥有一个平台来管理多个应用程序,用于多个环境,例如 heroku Web 变量创建,但更复杂。