したいこと
unicornの起動を成功させたい。(エラー文master failed to start, check stderr log for details)
経緯
本番環境としてEC2を使ってポートフォリオをデプロイしようとしています。
rails6で作成したアプリです。
下記記事を参考にしています。
https://qiita.com/Yuki_Nagaoka/items/dbb185feb6d4f051c2f2
https://qiita.com/naoki_mochizuki/items/5a1757d222806cbe0cd1#unicorn%E3%81%AE%E8%A8%AD%E5%AE%9A
出ているエラー
下記コマンドを実行し、
$ bundle exec unicorn_rails -c /var/www/rails/アプリ名/config/unicorn.conf.rb -D -E production
以下の様にエラーが表示される。
master failed to start, check stderr log for details
考えられる原因
・設定したunicorn.conf.rbに問題がある?
・unicornのバージョンが悪い?
・EC2にあるアプリのcredentials.yml.enc、master.key周りの設定?
とりあえずログを見る。
試したこと
unicornのエラーログを見るために下記を実行。
$ cd log
$ tail unicorn.log
間違っている部分は見つからず、よくわかりませんでした。
次にproduction.logをみるために下記を実行。
$ tail production.log
間違っている部分は見つからず、よくわかりませんでした。
次にunicorn_error.logを見るために下記を実行。
$ tail unicorn_error.log
ファイルがない、とのことで記録を見ることができませんでした。
次に、unicorn_stderr.logがあると思い下記を実行。
$ tail unicorn_stderr.log
ファイルがありませんでした。
次にアプリのディレクトリに戻り、下記を実行したところログが表示されました。
$ cat log/unicorn.log -n
気になるエラーが表示されました。
ActiveSupport::MessageEncryptor::InvalidMessage: ActiveSupport::MessageEncryptor::InvalidMessage
check_for_activated_spec!': You have already activated unicorn 5.5.4, but your Gemfile requires unicorn 5.4.1. Prepending bundle exec
to your command may solve this. (Gem::LoadError)
→調べたところそれぞれmaster.key周りのエラーとunicornのバージョンのエラー。
unicornのgemのバージョンが5.5.0の場合はエラーが出るとのことなので5.4.1に変えてみました。
参考記事→https://qiita.com/TeruhisaFukumoto/items/f1f0be91bc7b43b4f79d
→EC2内のアプリのgemを変えてbundle intallができたので、再び下記コマンドを実行したところ同じエラーが表示されました。
bundle exec unicorn_rails -c /var/www/rails/Portfolio/config/unicorn.conf.rb -D -E production
→すると下記のエラー。
master failed to start, check stderr log for details
先ほどおぼえたcat log/unicorn.log -nコマンドを使って558番以上の最新のログをみてみたところ、下記のエラー文が見つかりました。
ActiveSupport::MessageEncryptor::InvalidMessage: ActiveSupport::MessageEncryptor::InvalidMessage
ActiveSupport::MessageEncryptor::InvalidMessage: ActiveSupport::MessageEncryptor::InvalidMessageというエラー文があったのでcredentials.yml.enc、master.keyを確認。
ローカルのアプリにて以下を実施し、master.keyをメモ。
$ vi config/master.key
サーバー環境のアプリ内でmaster.keyを開きローカル環境のmaster.keyを貼り付け:wq。
$ vi config/master.key
ローカル環境にて下記コマンドでシークレットキーを発行し、サーバー環境にあるアプリのcredentials.yml.encに貼り付けて保存。
$ bundle exec rake secret
そして下記を実行したところ、同じエラーが表示されました。
$ bundle exec unicorn_rails -c /var/www/rails/Portfolio/config/unicorn.conf.rb -D -E production
ここまでの考察
・credentials.yml.enc、master.key周りの設定が怪しい。
・unicornのバージョンの問題はなし。
・ログの中にdirectory for pid=/home/username/appname/tmp/pids/unicorn.pid not writable (ArgumentError) というエラーが見つからないので、権限周りの問題ではない。
・ArgumentError: wrong number of arguments (given 0, expected 2) というエラーはないので、unicorn.conf.rbの設定ファイルによるエラーではない。
・他にエラーログがある?
というわけで、とりあえずローカル、サーバーのcredentials.yml.enc、master.key周りを確認してみる。
解決法
犯人はローカル環境にて行った$ bundle exec rake secretだった。
$ bundle exec rake secretにより、ローカル環境のmaster.key、credentials.yml.enc、サーバー環境のmaster.key、credentials.yml.encが噛み合わなくなっていたのが原因です。
私の環境はrails6.0。したがってcredentials.yml.enc
でのキーの管理をする必要がある。
もっと詳しくいうと、私は以前ローカル環境にあるmaster.key、credentials.yml.encを消して、ローカル環境で何回もEDITOR=vim bundle exec rails credentials:editをすることによって2つのキーを作っては壊しを繰り返してました。
当然サーバーとローカルの両アプリ内のキーが合わなくなるわけです。
ローカル、サーバーそれぞれ合計4つのmaster.key、credentials.yml.enc作成して紐づける手順
・ローカルのmaster.keyとcredentials.yml.encを手作業で削除し、以下コマンドで新しく2つのキーを作成し、secret key baseをコピーしておく。
ローカル.
EDITOR=vim bin/rails credentials:edit
※念の為目視でローカル環境のcinfig内に2つのキーが作られたか確認しましょう。
・次にサーバーのmaster.keyとcredentials.yml.encを以下のコマンドで削除。
サーバ.
[ユーザ名@ip-10-0-0-58 アプリ名]$ rm config/master.key
[ユーザ名@ip-10-0-0-58 アプリ名]$ rm config/credentials.yml.enc
ls configで消されたか確認。
サーバ.
[ユーザ名@ip-10-0-0-58 アプリ名]$ ls config
application.rb cable.yml database.yml environments locales routes.rb storage.yml unicorn.conf.rb webpacker.yml
boot.rb credentials environment.rb initializers puma.rb spring.rb unicorn webpack
消されている。
で、サーバー環境でEDITOR=vim bin/rails credentials:editをして2つのキーを作成し、vimの編集画面に入る。
編集画面ですかさずローカル環境の際にメモをしておいたsecret key baseを貼り付けます。
[ユーザ名@ip-10-0-0-58 アプリ名]$ EDITOR=vim bin/rails credentials:edit
Adding config/master.key to store the encryption key: d1616fa3117dd0c4a662c547e0c5ba28
Save this in a password manager your team can access.
If you lose the key, no one, including you, can access anything encrypted with it.
create config/master.key
File encrypted and saved.
作れた。
念の為目視でファイルがあるかどうか確認。
サーバ.
[ユーザ名@ip-10-0-0-58 アプリ名]$ ls config
application.rb cable.yml credentials.yml.enc environment.rb initializers master.key routes.rb storage.yml unicorn.conf.rb webpacker.yml
boot.rb credentials database.yml environments locales puma.rb spring.rb unicorn webpack
credentials.yml.enc、master.keyが作れている。
サーバー環境のmaster.keyは変更しない。そのままにする。ローカルと異なっていて良い。
で、本記事の本題である以下を実行。
[ユーザ名@ip-10-0-0-58 アプリ名]$ bundle exec unicorn_rails -c /var/www/rails/アプリ名/config/unicorn.conf.rb -D -E production
[ユーザ名@ip-10-0-0-58 アプリ名]$ ps -ef | grep unicorn | grep -v grep
ユーザ名 27923 1 2 07:13 ? 00:00:01 unicorn_rails master -c /var/www/rails/アプリ名/config/unicorn.conf.rb -D -E production
ユーザ名 27926 27923 0 07:13 ? 00:00:00 unicorn_rails worker[0] -c /var/www/rails/アプリ名/config/unicorn.conf.rb -D -E production
ユーザ名 27927 27923 0 07:13 ? 00:00:00 unicorn_rails worker[1] -c /var/www/rails/アプリ名/config/unicorn.conf.rb -D -E production
unicornが起動できたっぽい。
credentials.yml.encについての参考記事
https://qiita.com/scivola/items/cc06ddbfd94d3118f693
まとめ|この認識を持ちましょう。
master.key・・・カギ。
credentials.yml.enc・・・鍵穴。