如何解决错误“”生产环境“中缺less`secret_key_base`(Rails 4.1)

我从零开始创build了一个Rails应用程序(Rails 4.1),并且面临着一个我无法解决的奇怪问题。

每当我尝试在Heroku上部署我的应用程序时,都会收到错误500:

缺less'生产'环境的secret_key_base ,请在config/secrets.yml secret_key_base中设置此值

secret.yml文件包含以下configuration:

 secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> 

在Heroku上,我用“rake secret”命令的结果configuration了一个环境variables“SECRET_KEY_BASE”。 如果我启动“herokuconfiguration”,我可以看到具有正确名称和值的variables。

为什么我仍然得到这个错误?

非常感谢

我有同样的问题,我通过创build一个环境variables来解决它,每次login到生产服务器,并作出configuration它的步骤的迷你指南:

https://gist.github.com/pablosalgadom/4d75f30517edc6230a67

我正在使用Rails 4.1与Unicorn v4.8.2,当我试图部署我的应用程序它没有正常启动,并在unicorn.log文件中,我发现这个错误消息:

app error: Missing `secret_key_base` for 'production' environment, set this value in `config/secrets.yml` (RuntimeError)

经过一番研究,我发现Rails 4.1改变了pipe理secret_key的方式,所以如果你阅读位于exampleRailsProject/config/secrets.yml文件,你会发现如下所示:

 # Do not keep production secrets in the repository, # instead read values from the environment. production: secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> 

这意味着Railsbuild议您在生产服务器中为secret_key_base使用一个环境variables,为了解决这个错误,您应该按照以下步骤在生产服务器上为Linux(在我的情况下为Ubuntu)创build一个环境variables:

  1. 在生产服务器的terminal中执行下一个命令:

     $ RAILS_ENV=production rake secret 

    这将返回一个字母和数字的大string,复制(我们将引用该代码作为GENERATED_CODE)。

  2. login到您的服务器

    • 如果您以root用户身份login,请find该文件并对其进行编辑:

       $ vi /etc/profile 

      转到文件底部(在VI中为大写字母“GIFT + G”)

      用GENERATED_CODE编写你的环境variables(按“i”键写入VI),确保在文件末尾有一个新行:

       $ export SECRET_KEY_BASE=GENERATED_CODE 

      保存更改并closures文件(我们按“ESC”键,然后在“VI”中写入“:x”和“ENTER”键保存并退出)。

    • 但是,如果您以普通用户身份login,则可以将其称为“example_user”,您将需要find其他文件之一:

       $ vi ~/.bash_profile $ vi ~/.bash_login $ vi ~/.profile 

      这些文件是重要的,这意味着如果你有第一个文件,那么你就不需要写其他文件了。 所以如果你在你的目录~/.bash_profile~/.profilefind这两个文件,你只需要在第一个~/.bash_profile文件中写入,因为Linux只会读取这个文件而另一个文件将被忽略。

      然后我们到文件底部(在VI中为大写字母“SHIFT + G”)。

      我们将用我们的GENERATED_CODE编写我们的环境variables(按“i”键写入VI),确保在文件末尾有一个新行:

       $ export SECRET_KEY_BASE=GENERATED_CODE 

      编写代码后,保存修改并closures文件(我们按“ESC”键,然后在“VI”中写入“:x”和“ENTER”键保存退出)。

  3. 您可以使用以下命令validation我们的环境variables是否在Linux中正确设置:

     $ printenv | grep SECRET_KEY_BASE 

    或与:

     $ echo $SECRET_KEY_BASE 

    当你执行这个命令时,如果一切正常,它会显示你以前的GENERATED_CODE。 最后,在完成所有configuration后,您应该可以在不出现问题的情况下使用Unicorn或其他方式部署Rails应用程序。

当你closures你的shellterminal并重新login到生产服务器时,你将会设置这个环境variables并准备好使用它。

那就是它! 我希望这个迷你指南可以帮助你解决这个错误。

免责声明:我不是一个Linux或Rails大师,所以如果你发现错误或任何错误,我会很乐意修复它!

我将假设你没有把你的secrets.yml签入到源代码控制中(即它在.gitignore文件中)。 即使这不是你的情况,这是许多其他人看到这个问题已经做了,因为他们的代码暴露在Github上,不希望他们的秘密钥匙四处漂浮。

如果它不在源代码控制中,Heroku不知道它。 所以Rails正在寻找Rails.application.secrets.secret_key_base并且它没有被设置,因为Rails通过检查不存在的secrets.yml文件来设置它。 简单的解决方法是进入您的config/environments/production.rb文件并添加以下行:

 Rails.application.configure do ... config.secret_key_base = ENV["SECRET_KEY_BASE"] ... end 

这告诉您的应用程序使用环境variables设置密钥,而不是在secrets.yml中查找它。 这将节省我很多时间来了解这一点。

config/secrets.yml添加到版本控制并再次部署。 您可能需要从.gitignore删除一行,以便您可以提交该文件。

我有这个完全相同的问题,事实certificate,为我的Rails应用程序创build的样板.gitignore Github包括config/secrets.yml

这对我有效。

SSH进入你的生产服务器,并进入你的当前目录,运行bundle exec rake secretrake secret ,你会得到一个很长的string作为输出,复制该string。

现在运行sudo nano /etc/environment

粘贴在文件的底部

 export SECRET_KEY_BASE=rake secret ruby -e 'p ENV["SECRET_KEY_BASE"]' 

如果rake secret是刚才复制的string,请粘贴复制的string以代替rake secret

重新启动服务器并运行echo $SECRET_KEY_BASEtesting。

虽然你可以像其他答案一样使用初始化器,但是传统的Rails 4.1+方法是使用config/secrets.yml 。 Rails团队介绍这个的原因超出了这个答案的范围,但是TL; DR是这样的: secret_token.rb将configuration和代码secret_token.rb在一起,同时也是一个安全风险,因为令牌被签入源代码pipe理历史logging,唯一的系统需要知道生产密码的是生产基础设施。

你应该添加这个文件到.gitignore ,就像你不会添加config/database.yml到源代码控制一样。

引用Heroku自己的代码,在其Buildpack for Ruby中设置来自DATABASE_URL config/database.yml ,我最终将它们的repo分叉并修改它以从SECRETS_KEY_BASE环境variables创buildconfig/secrets.yml SECRETS_KEY_BASE

由于这个特性是在Rails 4.1中引入的,所以我觉得编辑./lib/language_pack/rails41.rb并添加这个function是适当的。

以下是我在公司创build的修改后的buildpack的片段 :

 class LanguagePack::Rails41 < LanguagePack::Rails4 # ... def compile instrument "rails41.compile" do super allow_git do create_secrets_yml end end end # ... # writes ERB based secrets.yml for Rails 4.1+ def create_secrets_yml instrument 'ruby.create_secrets_yml' do log("create_secrets_yml") do return unless File.directory?("config") topic("Writing config/secrets.yml to read from SECRET_KEY_BASE") File.open("config/secrets.yml", "w") do |file| file.puts <<-SECRETS_YML <% raise "No RACK_ENV or RAILS_ENV found" unless ENV["RAILS_ENV"] || ENV["RACK_ENV"] %> <%= ENV["RAILS_ENV"] || ENV["RACK_ENV"] %>: secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> SECRETS_YML end end end end # ... end 

你当然可以扩展这个代码来添加其他的秘密(如第三方的API密钥等),以便从你的环境variables中读取:

 ... <%= ENV["RAILS_ENV"] || ENV["RACK_ENV"] %>: secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> third_party_api_key: <%= ENV["THIRD_PARTY_API"] %> 

这样,你可以用一个非常标准的方式访问这个秘密:

 Rails.application.secrets.third_party_api_key 

在重新部署应用程序之前,请确保先设置您的环境variables: 在Heroku仪表板中设置SECRET_KEY_BASE

然后将你的修改后的buildpack(或者你非常欢迎链接到我的)添加到你的Heroku应用程序(参见Heroku的文档 )并重新部署你的应用程序。

每次git push送到Heroku时,buildpack会自动从环境variables中创buildconfig/secrets.yml ,作为dyno构build过程的一部分。

编辑:Heroku自己的文档build议创buildconfig/secrets.yml从环境variables读取,但这意味着你应该检查这个文件到源代码pipe理。 在我的情况下,这是行不通的,因为我已经硬编码的开发和testing环境的秘密,我宁愿不检查。

您可以将密钥导出为服务器的~/.bashrc~/.bash_profile上的环境variables:

 export SECRET_KEY_BASE = "YOUR_SECRET_KEY" 

然后,您可以获取.bashrc.bash_profile

 source ~/.bashrc source ~/.bash_profile 

永远不要提交你的secrets.yml

我做了什么:在我的生产服务器上,为Thin创build一个configuration文件(confthin.yml)(我正在使用它)并添加以下信息:

 environment: production user: www-data group: www-data SECRET_KEY_BASE: mysecretkeyproduction 

然后我启动应用程序

 thin start -C /whereeveristhefieonprod/configthin.yml 

像魅力一样工作,然后不需要在版本控制上拥有密钥

希望可以帮忙,但是我确定Unicorn和其他人可以做同样的事情。

我有一个补丁,我已经在Rails 4.1应用程序中使用,让我继续使用遗留密钥生成器(并因此向后兼容Rails 3),通过允许secret_key_base为空。

 Rails::Application.class_eval do # the key_generator will then use ActiveSupport::LegacyKeyGenerator.new(config.secret_token) fail "I'm sorry, Dave, there's no :validate_secret_key_config!" unless instance_method(:validate_secret_key_config!) def validate_secret_key_config! #:nodoc: config.secret_token = secrets.secret_token if config.secret_token.blank? raise "Missing `secret_token` for '#{Rails.env}' environment, set this value in `config/secrets.yml`" end end end 

我已经重新格式化的补丁提交给Rails作为一个合并请求

我已经创build了config/initializers/secret_key.rb文件,我只写了下面这行代码:

 Rails.application.config.secret_key_base = ENV["SECRET_KEY_BASE"] 

但是我认为@Erik Trautman发布的解决scheme更加优雅;)

编辑:哦,最后我在Heroku上find了这个build议: https ://devcenter.heroku.com/changelog-items/426 🙂

请享用!

这是很好的工作https://gist.github.com/pablosalgadom/4d75f30517edc6230a67为root用户应该编辑;

 $ /etc/profile 

但是如果你非root用户应该把生成代码放在下面

 $ ~/.bash_profile $ ~/.bash_login $ ~/.profile 

在Nginx / Passenger / Ruby(2.4)/ Rails(5.1.1)上除了:

服务器块中的/etc/nginx/sites-available/default中的passenger_env_var

资料来源: https : //www.phusionpassenger.com/library/config/nginx/reference/#passenger_env_var

在使用https://github.com/github/gitignore/blob/master/Rails.gitignore中的;.gitignore文件后,我遇到了同样的问题

我在.gitignore文件中注释了以下几行后,一切正常。

 config/initializers/secret_token.rb config/secrets.yml