Capistrano + Unicornの環境で構築すると、デプロイした内容が反映されない時がある。
ググってみると「stop → startすれば直るよ」と書いてある記事をよく見かけるが、それだと無停止デプロイできないし本番で使えないだろ、と思って原因を調べてみた。
原因
capistranoはデプロイ日時14桁のディレクトリを作成して、そこに新しいリソースをチェックアウトし、参紹ディレクトリを切り替える仕組みだが、これが古いディレクトリのままになっていた。
ページ内で __dir__
で現在のファイルのディレクトリパスを画面上に出すようにしたら、デプロイ後もデプロイ前のディレクトリになっていた。
capistrano/current
のリンク先は正常に変わっていたので、変わったリンク先を見てくれていないのが原因と判明。
対策
working_directoryを絶対パスに変更
unicorn.rbの設定方法の記事をみると、大抵の記事が以下のように書いてある。
app_path = File.expand_path('../../../', __FILE__)
working_directory "#{app_path}/current"
相対パスで書いてあり、環境に依存しない書き方で大変便利なのだが、これだとcapistranoの日時ディレクトリがworking_directoryに設定され、USR2シグナルの再起動では読み込み直されないもよう(もちろんHUPシグナルでも)。
なので、このworking_directoryをROOTからの絶対パスで書くようにした。
serviceの起動方法を変更
serviceの起動時も config/unicorn.rb
を相対パスで書いていた。
そのためか、serviceで起動したunicornはデプロイが反映されなかった。
cd $APP_ROOT && /usr/local/rbenv/shims/bundle exec unicorn -E $RAILS_ENV -c config/unicorn.rb -D
これも config/unicorn.rb
のパスをROOTからの絶対パスで書くようにした。
cd $APP_ROOT && /usr/local/rbenv/shims/bundle exec unicorn -E $RAILS_ENV -c ${APP_ROOT}config/unicorn.rb -D
結論
Capistrano + Pumaでこの現象になったことないので、Capistrano使うときはUnicorn使わない方が良いと思う。