How to solve error “Missing `secret_key_base` for 'production' environment” (Rails 4.1)
我从头开始创建了一个rails应用程序(rails 4.1),我遇到了一个我无法解决的奇怪问题。
每次我尝试在Heroku上部署我的应用程序时,都会收到错误500:
Missing
secret_key_base for 'production' environment, set this value inconfig/secrets.yml
secret.yml文件包含以下配置:
1 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> |
在Heroku上,我已经使用"rake secret"命令的结果配置了一个环境变量"SECRET_KEY_BASE"。 如果我启动"heroku config",我可以看到具有正确名称和值的变量。
为什么我仍然会收到此错误?
非常感谢
我遇到了同样的问题,我通过创建一个环境变量来解决它,每次登录到生产服务器时都会加载它并制作一个配置它的步骤的迷你指南:
https://gist.github.com/pablosalgadom/4d75f30517edc6230a67
我正在使用Rails 4.1和Unicorn v4.8.2,当我尝试部署我的应用程序时,它没有正确启动,在unicorn.log文件中我发现此错误消息:
经过一些研究后我发现Rails 4.1改变了管理secret_key的方式,所以如果你读了位于
1 2 3 4 | # Do not keep production secrets in the repository, # instead read values from the environment. production: secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> |
这意味着Rails建议您在生产服务器中为
在生产服务器的终端中执行下一个命令:
1 | $ RAILS_ENV=production rake secret |
这将返回一个包含字母和数字的大字符串,复制该字符串(我们将该代码称为GENERATED_CODE)。
登录您的服务器
-
如果以root用户身份登录,请找到此文件并进行编辑:
1$ vi /etc/profile转到文件的底部(VI中的大写字母G的"SHIFT + G")
使用GENERATED_CODE编写环境变量(按"i"键在VI中写入),请确保在文件末尾的新行中:
1$ export SECRET_KEY_BASE=GENERATED_CODE保存更改并关闭文件(按"ESC"键,然后写入":x"和"ENTER"键进行保存,然后退出VI)。
-
但是,如果您以普通用户身份登录,请将此名称称为"example_user",您需要找到以下其中一个文件:
1
2
3$ vi ~/.bash_profile
$ vi ~/.bash_login
$ vi ~/.profile这些文件按重要性排序,这意味着如果您有第一个文件,那么您就不需要写入其他文件。因此,如果您在目录
~/.bash_profile 和~/.profile 中找到了这两个文件,则只需要在第一个~/.bash_profile 中写入,因为Linux将只读取此文件而另一个将被忽略。然后我们转到文件的底部(VI中的大写字母G的"SHIFT + G")。
我们将使用GENERATED_CODE编写环境变量(按"i"键在VI中写入),请确保在文件末尾的新行中:
1$ export SECRET_KEY_BASE=GENERATED_CODE编写代码后,保存更改并关闭文件(按"ESC"键然后写入":x"和"ENTER"键进行保存并退出VI)。
您可以使用以下命令验证我们的环境变量是否在Linux中正确设置:
1 | $ printenv | grep SECRET_KEY_BASE |
或者:
1 | $ echo $SECRET_KEY_BASE |
执行此命令时,如果一切正常,它将显示之前的GENERATED_CODE。最后完成所有配置后,您应该可以使用Unicorn或其他方式部署没有问题的Rails应用程序。
当您关闭shell终端并再次登录到生产服务器时,您将设置此环境变量并准备使用它。
就是这样!!我希望这个迷你指南可以帮助您解决此错误。
免责声明:我不是Linux或Rails大师,所以如果您发现错误或任何错误,我将很乐意解决它!
我假设您没有将
如果它不在源代码管理中,Heroku不知道它。因此Rails正在寻找
1 2 3 4 5 | Rails.application.configure do ... config.secret_key_base = ENV["SECRET_KEY_BASE"] ... end |
这告诉应用程序使用环境变量设置密钥,而不是在
将
我有完全相同的问题,结果发现为我的Rails应用程序创建的样板
这对我有用。
SSH进入生产服务器,
现在运行
粘贴到文件的底部
1 2 | export SECRET_KEY_BASE=rake secret ruby -e 'p ENV["SECRET_KEY_BASE"]' |
其中
重新启动服务器并运行
虽然你可以像其他答案一样使用初始化器,但传统的Rails 4.1+方法是使用
您应该将此文件添加到
在他们的Buildpack for Ruby中引用Heroku自己的代码来从
由于此功能是在Rails 4.1中引入的,因此我觉得编辑
以下是我在公司创建的修改后的buildpack的片段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | 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密钥等)以从您的环境变量中读取:
1 2 3 4 | ... <%= ENV["RAILS_ENV"] || ENV["RACK_ENV"] %>: secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> third_party_api_key: <%= ENV["THIRD_PARTY_API"] %> |
这样,您就可以以非常标准的方式访问此秘密:
1 | Rails.application.secrets.third_party_api_key |
在重新部署应用程序之前,请务必先设置环境变量:
然后将您修改后的buildpack(或者您非常欢迎链接到我的)添加到您的Heroku应用程序(请参阅Heroku的文档)并重新部署您的应用程序。
每次
编辑:Heroku自己的文档建议创建
您可以将密钥导出为服务器的
1 | export SECRET_KEY_BASE ="YOUR_SECRET_KEY" |
然后,您可以获取
1 2 | source ~/.bashrc source ~/.bash_profile |
永远不要提交你的秘密
我做了什么 :
在我的生产服务器上,我为Thin创建了一个配置文件(confthin.yml)(我正在使用它)并添加以下信息:
1 2 3 4 | environment: production user: www-data group: www-data SECRET_KEY_BASE: mysecretkeyproduction |
然后我启动应用程序
1 | thin start -C /whereeveristhefieonprod/configthin.yml |
像魅力一样工作,然后无需在版本控制上使用密钥
希望它可以提供帮助,但我相信Unicorn和其他人可以做同样的事情。
Demi Magus的答案为我工作直到Rails 5。
在Apache2 / Passenger / Ruby(2.4)/ Rails(5.1.6)上,我不得不放
1 | export SECRET_KEY_BASE=GENERATED_CODE |
来自Demi Magus的回答在/ etc / apache2 / envvars中,导致/ etc / profile似乎被忽略了。
资料来源:https://www.phusionpassenger.com/library/indepth/environment_variables.html#apache
在Nginx / Passenger / Ruby(2.4)/ Rails(5.1.1)上没有其他工作,除了:
资料来源:https://www.phusionpassenger.com/library/config/nginx/reference/#passenger_env_var
这很好用https://gist.github.com/pablosalgadom/4d75f30517edc6230a67
对于root用户应该编辑
1 | $ /etc/profile |
但如果你非root应该把生成代码放在下面
1 2 3 4 5 | $ ~/.bash_profile $ ~/.bash_login $ ~/.profile |
我创建了
1 | Rails.application.config.secret_key_base = ENV["SECRET_KEY_BASE"] |
但我认为@Erik Trautman发布的解决方案更优雅;)
编辑:
哦,最后我在Heroku上找到了这个建议:https://devcenter.heroku.com/changelog-items/426 :)
请享用!
我有一个我在Rails 4.1应用程序中使用的补丁,让我继续使用遗留密钥生成器(因此与Rails 3的向后会话兼容性),允许secret_key_base为空。
1 2 3 4 5 6 7 8 9 10 | 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 |
我已经重新格式化了补丁,将其作为Pull请求提交给Rails
我使用https://github.com/github/gitignore/blob/master/Rails.gitignore中的.gitignore文件后遇到了同样的问题
在我评论.gitignore文件中的以下行之后,一切都很顺利。
1 2 | config/initializers/secret_token.rb config/secrets.yml |