Puma(Rails6)をsystemdで起動させる

puma

以前のPumaではdaemonizeオプションが用意されていましたが、Puma5.1で無くなりました。 Issueを見てみたところ、daemonizeはsystemd(やrunit)などのOSが提供しているものを利用してくれというスタンスのようです。

Puma公式のsystemdの書き方

こちらに記載されています(↓はv5.4.0のもの)。
puma/systemd.md at v5.4.0 · puma/puma

こんな感じに修正して利用しています。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# /etc/systemd/system/puma.service
[Unit]
Description=Puma HTTP Server
After=network.target

[Service]
# Puma supports systemd's `Type=notify` and watchdog service
# monitoring, if the [sd_notify](https://github.com/agis/ruby-sdnotify) gem is installed,
# as of Puma 5.1 or later.
# On earlier versions of Puma or JRuby, change this to `Type=simple` and remove
# the `WatchdogSec` line.
Type=notify

# If your Puma process locks up, systemd's watchdog will restart it within seconds.
WatchdogSec=10

User=rochefort

WorkingDirectory=/var/app/my_app/current

# Helpful for debugging socket activation, etc.
#Environment=PUMA_DEBUG=1
Environment=RAILS_ENV=production
Environment=RAILS_SERVE_STATIC_FILES=1

ExecStart=/bin/bash -lc 'bundle exec puma -C config/puma.rb'

Restart=always

[Install]
WantedBy=multi-user.target

以下、ポイントについて補足します。

Type

Puma5.1以上で sd_notify をinstallしている場合は、 notify を指定することでsystemdでシステム起動の異常を検知することが可能です。

それ以前は、 simple を指定します。(simpleだとコマンド実行で起動完了と判断されます。) この場合は、 WatchdogSec は不要です。

5.1以上にして、Gemfile に以下追加してinstallしておくのが良いでしょう。

# Gemfile
gem 'sd_notify'

Environment

環境変数ですが、この例では個別に指定していますが、 プロジェクト固有の環境変数が別ファイルで管理されているなどすれば(例えば .env や .envrc など)、EnvironmentFile が利用できます。

ExecStart

公式の例では以下のように記載されています。

ExecStart=/<FULLPATH>/bin/puma -C <YOUR_APP_PATH>/puma.rb

anyenv(rbenv) 利用時に、パスが長くなってしまいます。 (これでも良いのですが、プロジェクト毎に書き換える箇所が増えてしまいます。)

例)
ExecStart=//home/rochefort/.anyenv/envs/rbenv/shims/bundle exec puma -C /var/app/my_app/current/config/puma.rb

bash -lc を経由させることで、 .bash_profile を読み込ませた上で実行でき流ので、以下のようにsimpleに書けます。

ExecStart=/bin/bash -lc 'bundle exec puma -C config/puma.rb'

systemctlコマンド

公式ドキュメントには以下が記載されています。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# After installing or making changes to puma.service
systemctl daemon-reload

# Enable so it starts on boot
systemctl enable puma.service

# Initial start up.
systemctl start puma.service

# Check status
systemctl status puma.service

# A normal restart. Warning: listeners sockets will be closed
# while a new puma process initializes.
systemctl restart puma.service

これに加えて、エラー発生時は以下で確認していました。

1
sudo journalctl -fp err
updatedupdated2021-08-312021-08-31
コメントを読み込みますか?