Rails6 + CapistranoでのPumaのSystemdのデプロイ設定
株式会社TECH LUCKという会社で代表兼エンジニアをしている齊藤です。
DXプロジェクト、開発プロジェクト、Rails開発などでお困りごとがありましたら弊社HPからご相談をいただけますと幸いです。
以下のような問題に対応することが可能です。
- プロジェクトでRailsエンジニアが足りなくて困っている
- Railsのバージョンアップをしたいがノウハウ・リソースが足りなくて困っている
- オフショア開発をしているが、要件の齟齬やコード品質が悪いので改善したい
また、Railsエンジニアも募集しておりますので、興味がありましたら弊社HPからご連絡いただけますと幸いです。
前提
PumaをSystemdで起動させる際に、Capistranoでのデプロイでの設定になります。
環境
サーバー : AWS EC2
サーバーOS : Amazon Linux
Ruby : v2.7.3
Ruby on Rails : v6.1.4
Capistrano : v3.16.0
環境ごとにpuma.rbの作成
Railsアプリケーションのconfig
にpuma
ディレクトリを作成し、環境名のファイルを作成します。
cd config
mkdir puma
touch production.rb
環境ごとにPumaの設定ファイルを作成することにより、環境ごとにPumaの起動の設定を行うことができます。
詳細は以下の記事に書いてあるのでご参考まで。
Pumaではデフォルトの設定ファイルであるconfig/puma.rbのほか、実行環境に応じた、config/puma/環境名.rbという設定ファイルを用意できます。
rails sの場合はconfig/puma/[環境名].rb → config/puma.rbの優先順位で設定ファイルを読み込みます。
config/puma/production.rb
に以下の記述をします。
# bind "unix://#{Rails.root.join('tmp/sockets/puma.sock')}"だとpumactlコマンドで読み込まないため絶対パスで指定
root_dir = '/var/www/アプリケーション名/current'
max_threads_count = ENV.fetch('RAILS_MAX_THREADS', 5)
min_threads_count = ENV.fetch('RAILS_MIN_THREADS', max_threads_count)
threads min_threads_count, max_threads_count
worker_timeout 60
bind "unix://#{root_dir}/tmp/sockets/puma.sock"
environment 'production'
pidfile File.expand_path('tmp/pids/server.pid')
stdout_redirect File.expand_path('log/puma_access.log'), File.expand_path('log/puma_error.log'), true
# workerの数は適宜変更する。指定しない場合はsingle modeとなるが、指定した場合はcluster modeとなる。
workers 2
plugin :tmp_restart
systemdの登録
元々Pumaはdaemonizeオプションがあり、そのオプションを使うことでバックグラウンドで起動するようにデーモン化することができました。
しかし、そのdaemonizeオプションで起動がうまくいかなくなるバグがあるため、オプションが削除されたようです。
代わりに、LinuxのSystemdなどでPumaの起動やデーモン化を行うようにするようになったとのことです。
こちらの記事に詳細が記載されていますのでご参考までに。
本番サーバー(Capistranoでアプリがデプロイされるサーバー)にログインし、/etc/systemd/system
の配下にpuma.service
というファイル名で以下を記述します。
[Unit]
Description=Puma HTTP Server
After=network.target
[Service]
Type=simple
User=ユーザー名
WorkingDirectory=/var/www/アプリケーション名/current
Environment=RAILS_ENV=production
Environment=USING_WEB_SERVER=true
ExecStart=/bin/bash -lc 'bundle exec puma -C config/puma/production.rb'
Restart=always
[Install]
WantedBy=sockets.target
ファイルを作成したら、systemctlに登録するためのコマンドを実行します。
sudo systemctl enable puma.service
Capistranoの設定
Gemの追加とインストール
Gemfileに必要なgemを追加します。
gem 'puma' #元々あると思うが念の為
group :development do
gem 'capistrano3-puma', require: false
end
bundle install
bundle exec cap install
Capfileの編集
Capfile
に以下の記述を追加します。
# 追加する
require 'capistrano/puma'
...
...
...
# 追加する
install_plugin Capistrano::Puma
install_plugin Capistrano::Puma::Systemd
deploy.rbの編集
config/deploy.rb
に以下を追記します。
これにより、Capistranoのデプロイの際に、先ほど設定したsystemdでPumaを起動・再起動を行うようになります。
# 以下の記述を追加
set :puma_service_unit_name, 'puma.service'
デプロイ
以上の設定でCapistranoでPumaのデプロイを行うことができるようになります。
bundle exec cap production deploy
Rails7.1の場合の対処法
Rails7.1を利用していると、Railsのバージョンとの兼ね合いでpumaのバージョンを6.0以上にしないと、エラーが出るようになっていたのでpumaのバージョンをあげる。
gem 'puma', '~> 6.0'
また、capistrano3-puma
も普通にgemをインストールすると、pumaのバージョン6との相性が悪く、デプロイの際にエラーが発生するためバージョンを指定する。
gem 'capistrano3-puma', '6.0.0.beta.1', require: false
また、deploy.rb
の中でpuma_system_ctl_user
を:system
に指定しないと、以下のような形でpumaのリスタートが実行され、デプロイの際のpumaの起動の際にエラーが発生してしまう。
# :systemを指定していないと実行されるコマンド
/bin/systemctl --user restart puma.service
これを回避するため、以下をdeploy.rb
の中で指定する。
set :puma_systemctl_user, :system
また、Rails7.1からデフォルトで強制的にSSLがオンになっており、強制リダイレクトが発生して画面が見れないエラーが発生することもある。
environments/production.rb
の中で以下の指定を行いSSLの強制リダイレクトをOFFにする。
`config.force_ssl = false`
Discussion