なにこれ
筆者が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
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でエラーログを確認してみる。
cd /var/www/アプリ名/current/log/
cat unicorn.stderr.log
(ここだけ画像です!)
aws_accses_key_id と aws_secret_accses_key がArgumentError??
どういうこと?
そういえば、carrierwaveでAWSのキーを使ってた。
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'
}
上記を以下に変更
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の指定を変えるだけ。
app_path = File.expand_path('/var/www/アプリ名')
経緯
起動中のユニコーンのプロセスを確認します。
ps aux | grep unicorn
以下のやつしかいない。ok
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でパス指定を別にしたら、他エラーが出てきてユニコーンが起動できない。笑
app_path = File.expand_path('../../', __FILE__)
working_directory "#{app_path}/current"
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
ってどこだよ(哲学)
しょうがないので絶対パスにしてみる。
app_path = File.expand_path('/var/www/アプリ名')
bundle exec unicorn_rails -c config/unicorn.rb -E production -D
を叩いてコケる
エラーログをcat 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 %
通りました笑
経緯の手順
# 既にあるグループ内に追記
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
server '自身のElasticIP', user: 'ec2-user', roles: %w{app db web}
# ファイルが無いので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
# 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
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】を打つ
cd /var/www/アプリ名/releases
ll #=> 日付を表す数字の名前のフォルダが表示される 例:20200218063515
cd 一番下の数字 #=> 例 cd 20200218063515
rails db:create RAILS_ENV=production
EC2で【sudo vim /etc/nginx/conf.d/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】を叩いてコケる。