web-dev-qa-db-ja.com

「本番環境用のMissing `secret_key_base`」エラーを解決する方法(Rails 4.1)

最初から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」を起動すると、正しい名前と値の変数が表示されます。

それでもこのエラーが発生するのはなぜですか。

どうもありがとう

156
Paolo Laurenti

私は同じ問題を抱えていたので、本番サーバーにログインするたびにロードされる環境変数を作成し、それを構成するためのステップのミニガイドを作成しました。

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)用の環境変数を作成する必要があります。

  1. 運用サーバーの端末で次のコマンドを実行します。

    $ Rails_ENV=production rake secret
    

    これは文字と数字を含む大きな文字列を返します。それをコピーします(このコードをGENERATED_CODEと呼びます)。

  2. サーバーにログインする

    • 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で終了します)。

  3. このコマンドを使用して、Linuxで環境変数が正しく設定されていることを確認できます。

    $ printenv | grep SECRET_KEY_BASE
    

    またはと:

    $ echo $SECRET_KEY_BASE
    

    このコマンドを実行したときに、すべて問題なければ、以前のGENERATED_CODEが表示されます。最後に、設定がすべて完了したら、RailsアプリケーションをUnicornなどで問題なくデプロイできます。

シェル端末を閉じて本番サーバーに再度ログインすると、この環境変数が設定されて使用できるようになります。

以上です!!このミニガイドがこのエラーの解決に役立つことを願っています。

免責事項:私はLinuxやRailsの達人ではないので、あなたが何か問題やエラーを見つけた場合、私はそれを修正して嬉しいです!

197
Demi Magus

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で探すのではなく、環境変数を使って秘密鍵を設定するようにアプリケーションに指示します。これを前もって知ることは、私に多くの時間を節約させてくれたでしょう。

81
Erik Trautman

バージョン管理にconfig/secrets.ymlを追加して、再度デプロイしてください。ファイルをコミットできるように、.gitignoreから行を削除する必要があるかもしれません。

私はこれとまったく同じ問題を抱えていましたが、私のRailsアプリケーション用に作成された定型コード.gitignore Githubにconfig/secrets.ymlが含まれていることがわかりました。

56
danielricecodes

これは私のために働きました。

本番サーバーに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を実行してテストします。

13
sumitsv21

他の答えのようにイニシャライザを使用できますが、従来のRails 4.1+の方法はconfig/secrets.ymlを使用することです。 Railsチームがこれを導入する理由はこの回答の範囲を超えていますが、TL; DRは、トークンがソース管理履歴にチェックインされるため、secret_token.rbが構成とコードを圧縮し、セキュリティリスクになるためです生産秘密トークンを知る必要がある唯一のシステムは、生産インフラです。

ソース管理に.gitignoreを追加しないのと同じように、このファイルをconfig/database.ymlに追加する必要があります。

Ruby用のBuildpackconfig/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

アプリを再デプロイする前に、まず環境変数を設定してください: Setting SECRET_KEY_BASE in Heroku Dashboard

次に、変更したビルドパック(または、私のリンクに歓迎します)をHerokuアプリに追加し(Herokuの documentation を参照)、アプリを再デプロイします。

ビルドパックは、config/secrets.ymlをHerokuに接続するたびに、dynoビルドプロセスの一部として、環境変数からgit Pushを自動的に作成します。

編集:Heroku独自の documentation では、config/secrets.ymlを作成して環境変数から読み取ることを推奨していますが、これはこのファイルをソース管理にチェックインする必要があることを意味します。私の場合、開発環境とテスト環境の秘密をハードコードしているので、チェックインしたくないので、これはうまくいきません。

3
stackunderflow

サーバーの~/.bashrcまたは~/.bash_profileの環境変数として秘密鍵をエクスポートすることができます。

export SECRET_KEY_BASE = "YOUR_SECRET_KEY"

そして、あなたはあなたの.bashrcまたは.bash_profileを供給することができます:

source ~/.bashrc 
source ~/.bash_profile

あなたのsecrets.ymlを決してコミットしないでください

2
alessandrocb

私のしたこと:私の本番サーバーで、Thin用の設定ファイル(confthin.yml)を作成し(私はそれを使用しています)、次の情報を追加します。

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

それから私はアプリを起動します

thin start -C /whereeveristhefieonprod/configthin.yml

魅力的なように動作し、その後バージョン管理の秘密鍵を持っている必要はありません

それが助けになることを願っていますが、私はユニコーンと他の人たちと同じことができると確信しています。

1

私は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 :)

楽しい!

0
fadehelix

私の場合、問題はconfig/master.keyがバージョン管理下になく、別のコンピューターでプロジェクトを作成していたことです。

Railsが作成するデフォルトの.gitignoreは、このファイルを除外します。このファイルがないと展開できないため、チームメンバーのコンピューターから展開できるようにするには、ファイルをバージョン管理する必要があります。

解決策:config/master.keyから.gitignore行を削除し、プロジェクトが作成されたコンピューターからファイルをコミットします。これで、他のコンピューターでgit pullを展開できます。

人々は、代替ソリューションを提供せずに、これらのファイルの一部をバージョン管理にコミットしないと言っています。あなたがオープンソースプロジェクトに取り組んでいない限り、資格情報を含むプロジェクトの実行に必要なすべてをコミットしない理由はありません。

0
Andrew Koster

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

0
Kasperi

これはうまくいきます https://Gist.github.com/pablosalgadom/4d75f30517edc6230a67 rootユーザーは編集する必要があります

$ /etc/profile

あなたがrootでない場合は、生成コードを次のように書くべきです。

$ ~/.bash_profile

$ ~/.bash_login

$ ~/.profile
0
bung_firman

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

0
Florent L.

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

私はそれ以来 プルリクエストとしてRailsにそれを提出したパッチを再フォーマットしました

0
BF4