LoginSignup
9
8

More than 1 year has passed since last update.

【unicorn】master failed to start, check stderr log for detailsの解決法

Last updated at Posted at 2020-06-28

なにこれ

筆者がcapistranoでデプロイをするときに、
「master failed to start, check stderr log for details」
のエラーに7時間悩まされた話

01:57 unicorn:start
      01 $HOME/.rbenv/bin/rbenv exec bundle exec unicorn -c /var/www/MyNo…
      01 master failed to start, check stderr log for details

結論

自分の場合はかなり特例だと思います。
credentials.yml.encに以下の内容を追加したら解決しました。

ターミナル.
EDITOR='vim --wait' rails credentials:edit

credentials.yml
aws:
  AWS_ACCESS_KEY_ID: <YOUR_AWS_ACCESS_KEY_ID>
  AWS_SECRET_ACCESS_KEY: <YOUR_AWS_SECRET_ACCESS_KEY>

「master failed to start, check stderr log for details」で検索すると、
unicornのバージョン変更や編集権限の記事がヒットするのですが、
自分の場合は全く違いました。

経緯

VPCの関係でEC2インスタンスを作り直したのが発端です。
既存のアプリを新しいEC2に引っ越ししました。
ほとんど完成した状態でAWSのアクセスキーなどの記述がありました。

手順は後述。
ローカルで【bundle exec cap production deploy】
タイトルのエラーでコケる←ここで7時間ハマる

エラーログをよく見て原因を考える

ターミナル.
01:57 unicorn:stop
      unicorn is not running...
01:57 unicorn:start
      01 $HOME/.rbenv/bin/rbenv exec bundle exec unicorn -c /var/www/MyNo…
      01 master failed to start, check stderr log for details

#<Thread:0x00007fbc0da2b5e0@/Users/ohishikaido/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/sshkit-1.21.0/lib/sshkit/runners/parallel.rb:10 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
        1: from /Users/ohishikaido/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/sshkit-1.21.0/lib/sshkit/runners/parallel.rb:11:in `block (2 levels) in execute'
/Users/ohishikaido/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/sshkit-1.21.0/lib/sshkit/runners/parallel.rb:15:in `rescue in block (2 levels) in execute'

Exception while executing as kaito@3.113.216.56: bundle exit status: 1 (SSHKit::Runner::ExecuteError)
bundle stdout: Nothing written
bundle stderr: master failed to start, check stderr log for details
(Backtrace restricted to imported tasks)

cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing as kaito@3.113.216.56: bundle exit status: 1
bundle stdout: Nothing written
bundle stderr: master failed to start, check stderr log for details

Caused by:
SSHKit::Command::Failed: bundle exit status: 1
bundle stdout: Nothing written
bundle stderr: master failed to start, check stderr log for details
Tasks: TOP => unicorn:start
(See full trace by running task with --trace)

The deploy has failed with an error: Exception while executing as kaito@3.113.216.56: bundle exit status: 1
bundle stdout: Nothing written
bundle stderr: master failed to start, check stderr log for details

「01:57 unicorn:start」で失敗してる。
EC2でエラーログを確認してみる。

EC2.
cd /var/www/アプリ名/current/log/
cat unicorn.stderr.log

(ここだけ画像です!)
エラー文.png
aws_accses_key_id と aws_secret_accses_key がArgumentError??
どういうこと?
そういえば、carrierwaveでAWSのキーを使ってた。

carrierwave.rb
    config.fog_credentials = {
      provider: 'AWS',
      aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
      aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
      region: 'ap-northeast-1'
    }

上記を以下に変更

carrierwave.rb
    config.fog_credentials = {
      provider: 'AWS',
      aws_access_key_id: Rails.application.credentials.aws[:AWS_ACCESS_KEY_ID],
      aws_secret_access_key: Rails.application.credentials.aws[:AWS_SECRET_ACCESS_KEY],
      region: 'ap-northeast-1'
    }

そして、冒頭の結論に書いてあるcredentials.ymlに記述を行う。
commit&pushしてデプロイすると解決しました。

感想

一度carrierwave.rbのENV['AWS_ACCESS_KEY_ID']の記述をコメントアウトして
デプロイしてみたんですけど、同じエラーでコケました。
アクセスキーに関する記述があると、どこかでアクセスキーを書いてないとエラーが出るっていう感じなんですね。
勉強になりました!

余談

EC2で【sudo vim /etc/environment】を叩いて、
そちらにAWS_ACCESS_KEY_IDとAWS_SECRET_ACCESS_KEYを書いても成功しました。
管理しやすいと思って、credentials.ymlに書くことにしました。

EC2からユニコーンが再起動できない!問題を解決

結論

unicorn.rbのapp_pathの指定を変えるだけ。

config/unicorn.rb
app_path = File.expand_path('/var/www/アプリ名')

経緯

起動中のユニコーンのプロセスを確認します。

EC2.
ps aux | grep unicorn

以下のやつしかいない。ok

EC2.
ec2-user 32720  0.0  0.2 110536  2180 pts/1    S+   22:49   0:00 grep --color=auto unicorn

【bundle exec unicorn_rails -c config/unicorn.rb -E production -D】
を叩いても、タイトルのエラーでコケます!
【bundle exec cap production deploy】が通るのに、
EC2のcurrentで通らない。。。謎みが深い。

コマンドをRAILS_SERVE_STATIC_FILES=1 unicorn_rails -c config/unicorn.rb -E production -Dに変えてもダメでした。。
sudo service mysqld restartもやりました。

エラー文.
bundler: failed to load command: unicorn_rails (/var/www/MyNote/shared/bundle/ruby/2.5.0/bin/unicorn_rails)
ArgumentError: config_file=config/unicorn.rb would not be accessible in working_directory=/var/www/MyNote/releases/current
(中略)
master failed to start, check stderr log for details

うーん、原因がよく分からない。
/var/www/MyNote/releases/currentっていうパスだから、
/MyNote/releases/current/が悪いのは分かる。
そんなパスは存在しないので。
でも、unicorn.rbでパス指定を別にしたら、他エラーが出てきてユニコーンが起動できない。笑

config/unicorn.rb
app_path = File.expand_path('../../', __FILE__)
working_directory "#{app_path}/current"

EC2.
bundler: failed to load command: unicorn_rails (/var/www/MyNote/shared/bundle/ruby/2.5.0/bin/unicorn_rails)

ArgumentError: config_file=config/unicorn.rb would not be accessible in working_directory=/var/www/MyNote/releases/20200628222655/current

bundle exec unicorn_rails -c config/unicorn.rb -E production -Dを叩いてコケる
~/MyNote/releases/20200628222655/currentってどこだよ(哲学)

しょうがないので絶対パスにしてみる。

config/unicorn.rb
app_path = File.expand_path('/var/www/アプリ名')

bundle exec unicorn_rails -c config/unicorn.rb -E production -Dを叩いてコケる
エラーログをcat log/unicorn.stderr.logで確認します!

log/unicorn.stderr.log
bundler: failed to load command: unicorn_rails (/var/www/MyNote/shared/bundle/ruby/2.5.0/bin/unicorn_rails)
ArgumentError: Already running on PID:31334 (or pid=/var/www/MyNote/shared/tmp/pids/unicorn.pid is stale)

PIDが生きてるのでkillします。

ps aux | grep unicorn
kill -9 プロセス番号

ユニコーン起動できた〜

ec2-user   612 38.0 11.3 509012 114744 ?       Sl   23:43   0:01 unicorn_rails master -c config/unicorn.rb -E production -D                                                                                            
ec2-user   617  0.0 10.6 510088 107676 ?       Sl   23:43   0:00 unicorn_rails worker[0] -c config/unicorn.rb -E production -D                                                                                         
ec2-user   622  0.0  0.2 110536  2144 pts/1    S+   23:43   0:00 grep --color=auto unicorn

今までの手順はEC2からvimでいじっただけなので、bundle exec cap production deploy
を叩いてみる。

00:48 deploy:log_revision
      01 echo "Branch master (at f7a05267807ec5da99859b9a14bf49c494547dac) deployed as release 202…
    ✔ 01 ec2-user@13.114.24.148 0.469s
ohishikaido@ohishi-MacBook-Air my_app % 

通りました笑

経緯の手順

Gemfile.
# 既にあるグループ内に追記
group :development, :test do
  gem 'pry-rails'
  gem 'capistrano'
  gem 'capistrano-rbenv'
  gem 'capistrano-bundler'
  gem 'capistrano-rails'
  gem 'capistrano3-unicorn'
  gem 'capistrano-rails-console'
end

# 以下全てをGemfile下部にコピー
group :production do
  gem 'unicorn', '5.4.1'
end

config/deploy/production.rb
server '自身のElasticIP', user: 'ec2-user', roles: %w{app db web}

config/unicorn.rb(新規作成)
# ファイルが無いのでconfigフォルダにunicorn.rbを新規作成します

app_path = File.expand_path('../../../', __FILE__)

worker_processes 1

working_directory "#{app_path}/current"
pid "#{app_path}/shared/tmp/pids/unicorn.pid"
listen "#{app_path}/shared/tmp/sockets/unicorn.sock"
stderr_path "#{app_path}/shared/log/unicorn.stderr.log"
stdout_path "#{app_path}/shared/log/unicorn.stdout.log"

timeout 60

preload_app true
GC.respond_to?(:copy_on_write_friendly=) && GC.copy_on_write_friendly = true

check_client_connection false

run_once = true

before_fork do |server, worker|
  defined?(ActiveRecord::Base) &&
    ActiveRecord::Base.connection.disconnect!

  if run_once
    run_once = false # prevent from firing again
  end

  old_pid = "#{server.config[:pid]}.oldbin"
  if File.exist?(old_pid) && server.pid != old_pid
    begin
      sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
      Process.kill(sig, File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH => e
      logger.error e
    end
  end
end

after_fork do |_server, _worker|
  defined?(ActiveRecord::Base) && ActiveRecord::Base.establish_connection
end

config/deploy.rb
# Gemfile.lockを見てcapistranoのバージョンを入れる
lock 'xx.xx.x'

# 自身のアプリ名、リポジトリ名を記述
set :application, 'アプリ名'
set :repo_url,  'git@github.com:githubのユーザー名/リポジトリ名.git'

set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system', 'public/uploads')

set :rbenv_type, :user
set :rbenv_ruby, '2.5.1'

# chat-spaceで使ったpemを指定
set :ssh_options, auth_methods: ['publickey'],
                  keys: ['~/.ssh/xxx.pem']

set :unicorn_pid, -> { "#{shared_path}/tmp/pids/unicorn.pid" }
set :unicorn_config_path, -> { "#{current_path}/config/unicorn.rb" }
set :keep_releases, 5

set :linked_files, %w{ config/master.key }

after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
  task :restart do
    invoke 'unicorn:stop'
    invoke 'unicorn:start'
  end

  desc 'upload master.key'
  task :upload do
    on roles(:app) do |host|
      if test "[ ! -d #{shared_path}/config ]"
        execute "mkdir -p #{shared_path}/config"
      end
      upload!('config/master.key', "#{shared_path}/config/master.key")
    end
  end
  before :starting, 'deploy:upload'
  after :finishing, 'deploy:cleanup'
end

config/database.yml
production:
  <<: *default
  database: 本番環境のDB名
  username: root
  password: password
  socket: /var/lib/mysql/mysql.sock
  encoding: utf8

EC2で【sudo service mysqld start】を打つ
ローカルで【bundle exec cap production deploy】を打つ

unknown databaseが出るので、EC2の適当な場所で、
 【rails db:create RAILS_ENV=production】を打つ

EC2.
cd /var/www/アプリ名/releases
ll            #=> 日付を表す数字の名前のフォルダが表示される 例:20200218063515
cd 一番下の数字 #=> 例 cd 20200218063515
rails db:create RAILS_ENV=production

EC2で【sudo vim /etc/nginx/conf.d/rails.conf】を叩いて編集

rails.conf
upstream app_server {
  server unix:/var/www/アプリ名/shared/tmp/sockets/unicorn.sock;
}

server {
  listen 80;
  server_name ご自身のElastic IP;

  root /var/www/アプリ名/current/public;

  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
    root   /var/www/アプリ名/current/public;
  }

  try_files $uri/index.html $uri @unicorn;

  location @unicorn {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://app_server;
  }

  error_page 500 502 503 504 /500.html;
}

EC2で【sudo service nginx start】を打つ
ローカルで【bundle exec cap production deploy】を叩いてコケる。

9
8
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8