如何解决错误“”生产环境“中缺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:
-
在生产服务器的terminal中执行下一个命令:
$ RAILS_ENV=production rake secret
这将返回一个字母和数字的大string,复制(我们将引用该代码作为GENERATED_CODE)。
-
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
和~/.profile
find这两个文件,你只需要在第一个~/.bash_profile
文件中写入,因为Linux只会读取这个文件而另一个文件将被忽略。然后我们到文件底部(在VI中为大写字母“SHIFT + G”)。
我们将用我们的GENERATED_CODE编写我们的环境variables(按“i”键写入VI),确保在文件末尾有一个新行:
$ export SECRET_KEY_BASE=GENERATED_CODE
编写代码后,保存修改并closures文件(我们按“ESC”键,然后在“VI”中写入“:x”和“ENTER”键保存退出)。
-
-
您可以使用以下命令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 secret
或rake 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_BASE
testing。
虽然你可以像其他答案一样使用初始化器,但是传统的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:
然后将你的修改后的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