最初からRailsアプリ(Rails 4.1)を作成しましたが、解決できない奇妙な問題に直面しています。
Herokuにアプリをデプロイしようとするたびに、エラー500が発生します。
'本番'環境用の
secret_key_base
がありません。この値をconfig/secrets.yml
に設定してください
Secret.ymlファイルには以下の設定が含まれています。
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
Herokuでは、 "rake secret"コマンドの結果を使って環境変数 "SECRET_KEY_BASE"を設定しました。 「heroku config」を起動すると、正しい名前と値の変数が表示されます。
それでもこのエラーが発生するのはなぜですか。
どうもありがとう
私は同じ問題を抱えていたので、本番サーバーにログインするたびにロードされる環境変数を作成し、それを構成するためのステップのミニガイドを作成しました。
https://Gist.github.com/pablosalgadom/4d75f30517edc6230a67
Unicorn v4.8.2でRails 4.1を使用していましたが、アプリをデプロイしようとすると、正しく起動されず、Unicorn.logファイルに次のエラーメッセージが表示されました。
app error: Missing `secret_key_base` for 'production' environment, set this value in `config/secrets.yml` (RuntimeError)
いくつかの調査の結果、Rails 4.1ではsecret_keyの管理方法が変更されたことがわかりました。したがって、exampleRailsProject/config/secrets.yml
にあるsecrets.ymlファイルを読むと、次のようになります。
# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
つまり、Railsでは、運用サーバーでsecret_key_base
に環境変数を使用することをお勧めします。このエラーを解決するには、運用サーバーにLinux(私の場合はUbuntu)用の環境変数を作成する必要があります。
運用サーバーの端末で次のコマンドを実行します。
$ Rails_ENV=production rake secret
これは文字と数字を含む大きな文字列を返します。それをコピーします(このコードをGENERATED_CODEと呼びます)。
サーバーにログインする
Rootユーザーとしてログインした場合は、このファイルを見つけて編集します。
$ vi /etc/profile
ファイルの一番下に移動します(VIの大文字Gの場合は「SHIFT + G」)。
GENERATED_CODE(VIを書き込むには "i"キーを押します)を使用して環境変数を書きます。ファイルの最後に必ず新しい行を入れてください。
$ export SECRET_KEY_BASE=GENERATED_CODE
変更を保存してファイルを閉じます(保存するには "ESC"キーを押し、次に ":x"と "ENTER"キーを押してVIを終了します)。
しかし、もしあなたが普通のユーザーとしてログインするならば、それをこの要旨のために "example_user"と呼ぶことを可能にするなら、あなたはこの他のファイルのうちの1つを見つける必要があるでしょう:
$ vi ~/.bash_profile
$ vi ~/.bash_login
$ vi ~/.profile
これらのファイルは重要度の順になっています。つまり、最初のファイルがあれば、他のファイルに書き込む必要はありません。そのため、ディレクトリ~/.bash_profile
と~/.profile
にこの2つのファイルが見つかった場合は、最初の1つに~/.bash_profile
を書き込むだけで済みます。Linuxではこれだけが読み込まれ、もう1つは無視されるためです。
次に、ファイルの一番下に移動します(VIの大文字Gの場合は「SHIFT + G」)。
そして、GENERATED_CODEを使って環境変数を書きます(VIに書き込むには "i"キーを押します)。ファイルの最後に必ず改行してください。
$ export SECRET_KEY_BASE=GENERATED_CODE
コードを書き終えたら、変更を保存してファイルを閉じます( "ESC"キーを押してから ":x"と "ENTER"キーを押して保存し、VIで終了します)。
このコマンドを使用して、Linuxで環境変数が正しく設定されていることを確認できます。
$ printenv | grep SECRET_KEY_BASE
またはと:
$ echo $SECRET_KEY_BASE
このコマンドを実行したときに、すべて問題なければ、以前のGENERATED_CODEが表示されます。最後に、設定がすべて完了したら、RailsアプリケーションをUnicornなどで問題なくデプロイできます。
シェル端末を閉じて本番サーバーに再度ログインすると、この環境変数が設定されて使用できるようになります。
以上です!!このミニガイドがこのエラーの解決に役立つことを願っています。
免責事項:私は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
これはsecrets.yml
で探すのではなく、環境変数を使って秘密鍵を設定するようにアプリケーションに指示します。これを前もって知ることは、私に多くの時間を節約させてくれたでしょう。
バージョン管理にconfig/secrets.yml
を追加して、再度デプロイしてください。ファイルをコミットできるように、.gitignore
から行を削除する必要があるかもしれません。
私はこれとまったく同じ問題を抱えていましたが、私のRailsアプリケーション用に作成された定型コード.gitignore
Githubにconfig/secrets.yml
が含まれていることがわかりました。
これは私のために働きました。
本番サーバーにSSHでアクセスし、現在のディレクトリにcd
を実行します。bundle exec rake secret
またはrake secret
を実行すると、長い文字列が出力として表示されます。その文字列をコピーします。
今Sudo nano /etc/environment
を実行してください。
ファイルの末尾に貼り付ける
export SECRET_KEY_BASE=rake secret
Ruby -e 'p ENV["SECRET_KEY_BASE"]'
rake secret
が先ほどコピーした文字列である場合は、そのコピーした文字列をrake secret
の代わりに貼り付けます。
サーバーを再起動し、echo $SECRET_KEY_BASE
を実行してテストします。
他の答えのようにイニシャライザを使用できますが、従来のRails 4.1+の方法はconfig/secrets.yml
を使用することです。 Railsチームがこれを導入する理由はこの回答の範囲を超えていますが、TL; DRは、トークンがソース管理履歴にチェックインされるため、secret_token.rb
が構成とコードを圧縮し、セキュリティリスクになるためです生産秘密トークンを知る必要がある唯一のシステムは、生産インフラです。
ソース管理に.gitignore
を追加しないのと同じように、このファイルをconfig/database.yml
に追加する必要があります。
Ruby用のBuildpack でconfig/database.yml
からDATABASE_URL
をセットアップするためにHeroku自身のコードを参照し、最終的に repoをフォーク に変更し、config/secrets.yml
環境変数からSECRETS_KEY_BASE
を作成するように変更しました。
この機能はRails 4.1で導入されたため、./lib/language_pack/Rails41.rb
を編集してこの機能を追加することが適切であると感じました。
以下は、会社で作成した修正ビルドパックの snippet です。
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キーなど)を追加できます。
...
<%= 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
アプリを再デプロイする前に、まず環境変数を設定してください:
次に、変更したビルドパック(または、私のリンクに歓迎します)をHerokuアプリに追加し(Herokuの documentation を参照)、アプリを再デプロイします。
ビルドパックは、config/secrets.yml
をHerokuに接続するたびに、dynoビルドプロセスの一部として、環境変数からgit Push
を自動的に作成します。
編集:Heroku独自の documentation では、config/secrets.yml
を作成して環境変数から読み取ることを推奨していますが、これはこのファイルをソース管理にチェックインする必要があることを意味します。私の場合、開発環境とテスト環境の秘密をハードコードしているので、チェックインしたくないので、これはうまくいきません。
サーバーの~/.bashrc
または~/.bash_profile
の環境変数として秘密鍵をエクスポートすることができます。
export SECRET_KEY_BASE = "YOUR_SECRET_KEY"
そして、あなたはあなたの.bashrc
または.bash_profile
を供給することができます:
source ~/.bashrc
source ~/.bash_profile
あなたのsecrets.ymlを決してコミットしないでください
私のしたこと:私の本番サーバーで、Thin用の設定ファイル(confthin.yml)を作成し(私はそれを使用しています)、次の情報を追加します。
environment: production
user: www-data
group: www-data
SECRET_KEY_BASE: mysecretkeyproduction
それから私はアプリを起動します
thin start -C /whereeveristhefieonprod/configthin.yml
魅力的なように動作し、その後バージョン管理の秘密鍵を持っている必要はありません
それが助けになることを願っていますが、私はユニコーンと他の人たちと同じことができると確信しています。
私はconfig/initializers/secret_key.rb
ファイルを作成しました、そして、私は以下のコード行だけを書きました:
Rails.application.config.secret_key_base = ENV["SECRET_KEY_BASE"]
しかし、私は @ Erik Trautman によって投稿された解決策がよりエレガントだと思います。
編集:ああ、そして最後に私はHerokuでこのアドバイスを見つけました: https://devcenter.heroku.com/changelog-items/426 :)
楽しい!
私の場合、問題はconfig/master.key
がバージョン管理下になく、別のコンピューターでプロジェクトを作成していたことです。
Railsが作成するデフォルトの.gitignoreは、このファイルを除外します。このファイルがないと展開できないため、チームメンバーのコンピューターから展開できるようにするには、ファイルをバージョン管理する必要があります。
解決策:config/master.key
から.gitignore
行を削除し、プロジェクトが作成されたコンピューターからファイルをコミットします。これで、他のコンピューターでgit pull
を展開できます。
人々は、代替ソリューションを提供せずに、これらのファイルの一部をバージョン管理にコミットしないと言っています。あなたがオープンソースプロジェクトに取り組んでいない限り、資格情報を含むプロジェクトの実行に必要なすべてをコミットしない理由はありません。
Nginx/Passenger/Ruby(2.4)/ Rails(5.1.1)では、他に何もしなかった:
サーバーブロックのpassenger_env_var
内の/etc/nginx/sites-available/default
。
出典: https://www.phusionpassenger.com/library/config/nginx/reference/#passenger_env_var
これはうまくいきます https://Gist.github.com/pablosalgadom/4d75f30517edc6230a67 rootユーザーは編集する必要があります
$ /etc/profile
あなたがrootでない場合は、生成コードを次のように書くべきです。
$ ~/.bash_profile
$ ~/.bash_login
$ ~/.profile
Demi Magusの答えはRails 5まで私のために働きました。
Apache2/Passenger/Ruby(2.4)/ Rails(5.1.6)では、次のように書きました。
export SECRET_KEY_BASE=GENERATED_CODE
/ etc/Apache2/envvarsのDemi Magusの回答から、/ etc/profileは無視されるようです。
出典: https://www.phusionpassenger.com/library/indepth/environment_variables.html#Apache
Secret_key_baseを空白にして、レガシキージェネレータを引き続き使用できるようにする(したがってRails 3とのセッションの後方互換性を維持する)ためにRails 4.1アプリで使用したパッチがあります。
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