systemd の基本:サービスを自分で作る
Linux を日常的に使っていると、何かしらのデーモンを自分で管理したくなる場面が出てきます。 たとえば、自作のバックアップスクリプトを定期的に走らせたい、あるいは開発用の小さなサーバーをシステム起動時に自動で立ち上げたい ―― そういったときに頼りになるのが systemd の Unit ファイルです。
本記事では Unit ファイルの最小構成から始めて、enable・start・ログ確認まで一通りの流れを紹介します。
慣れてしまえば数分で書けるようになるので、ぜひ一度手を動かしてみましょう。
Unit ファイルの構成
Unit ファイルは /etc/systemd/system/ に置くテキストファイルです。
[Unit]、[Service]、[Install] の3セクションで構成されており、最小限の記述でサービスとして登録できます。
# /etc/systemd/system/myapp.service
[Unit]
Description=My Custom Application
After=network.target
[Service]
Type=simple
User=myuser
ExecStart=/usr/local/bin/myapp
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
[Unit] セクション
Description にはサービスの説明を書きます。After=network.target を指定すると、ネットワークが使用可能になってからサービスを起動するよう依存関係を設定できます。
[Service] セクション
実際に実行するコマンドを ExecStart に指定します。User でサービスを実行するユーザーを限定することで、余計な権限を与えずに済みます。
[Install] セクション
WantedBy=multi-user.target が最も一般的な設定です。これにより systemctl enable したときに、通常のマルチユーザーモードで自動起動するようリンクが張られます。
基本コマンドの流れ
Unit ファイルを作成または編集したあとは、daemon-reload で systemd に変更を読み込ませる必要があります。
# Unit ファイルを systemd に再読み込みさせる
sudo systemctl daemon-reload
# サービスをすぐに起動し、かつ自動起動も有効にする
sudo systemctl enable --now myapp
# サービスの状態を確認する
sudo systemctl status myapp
# ログをリアルタイムで追いかける
sudo journalctl -u myapp -f
enable --now は enable と start を一度に行う便利なオプションです。Unit ファイルを書いたら、まずこれを叩くのが習慣になると良いでしょう。
自動再起動の設定
Restart=on-failure を [Service] セクションに追加しておくと、プロセスが予期せず終了したときに自動で再起動してくれます。本番環境での運用を想定するなら、この設定は最初から入れておくことをおすすめします。
また RestartSec=5 で再起動までの待機時間を秒単位で設定できます。連続クラッシュを防ぐため、短くしすぎず適切な間隔を設定しましょう。
[Service]
ExecStart=/usr/local/bin/myapp
Restart=on-failure
RestartSec=5
# 最大リスタート試行回数を制限したい場合
StartLimitIntervalSec=60
StartLimitBurst=3
よく使うデバッグコマンド
# 直近のログを20行表示する
sudo journalctl -u myapp -n 20
# エラーのみ表示する
sudo journalctl -u myapp -p err
# 今回の起動以降のログだけを見る
sudo journalctl -u myapp -b
# サービス一覧と状態を確認する
systemctl list-units --type=service --state=running
まとめ
systemd の Unit ファイルは一見とっつきにくいですが、基本構成を把握してしまえばあとは応用するだけです。 自作スクリプトをデーモン化したいときや、開発用サーバーをシステム起動時に自動で上げたいときなど、活躍の場は意外と多くあります。まずは小さなスクリプトをサービス化するところから試してみてください。