自動起動させたいサービスやジョブを systemd のユニットファイルにまとめて、sudo systemctl enable myservice.service といったコマンドで登録するシーンがよくあると思います。
しかし恥ずかしながら長らくユーザー固有のジョブも登録できることを知らなかったため備忘録。
ユーザー固有の systemd ユニットファイルを追加
~/.config/systemd/user/ 以下にユニットファイルを作成します。
この際、/etc/systemd/system に設置するシステム全体向けユニットファイルとはいくつかの違いがあります。
User や Group の使用
システム全体向けユニットファイルでは User や Group を指定しますが、ユーザーレベルのユニットファイルではこれらを使用できません。
[Service]
User=username
Group=groupname
multi-user.target の代替
ユーザー固有のユニットファイルでは multi-user ターゲットは指定できません。
代わりに default.target を指定する必要があります。
[Install]
- WantedBy=multi-user.target
+ WantedBy=default.target
サンプルユニットファイル
以下は上記の点に注意して書いた、Pumaを起動する myservice サービスのサンプルユニットファイルです。
~/.config/systemd/user/myservice.service
[Unit]
Description=Puma HTTP Server
After=network.target
[Service]
Type=simple
Environment=PUMA_DEBUG=1
WorkingDirectory=/var/www/app/myservice/current
ExecStart=/home/username/.rbenv/bin/rbenv exec bundle exec puma -e production -C /var/www/app/myservice/current/config/puma.rb
ExecStop=/home/username/.rbenv/bin/rbenv exec bundle exec pumactl -S /var/www/app/myservice/shared/tmp/pids/puma.state stop
ExecReload=/bin/kill -USR1 $MAINPID
Restart=always
KillMode=mixed
[Install]
WantedBy=default.target
サービスの起動
システム全体のユニットファイルなら sudo systemctl start myservice.service としますが、ユーザー固有のサービスを操作するためには --user オプションを使用します。
systemctl --user start myservice.service
自動起動の設定も同様に --user オプションを使用します。
systemctl --user enable myservice.service
しかしこれだけではユーザーがログアウトするとサービスが停止してしまいます。
そこでログアウトしてもサービスが持続するように linger 設定を追加します。
sudo loginctl enable-linger username
これでユーザーがログアウトしてもサービスが立ち上がり続けます。
サービスが起動しない場合
- ログファイルを確認する:
journalctl --user -u myservice.service でサービスのログを確認し、エラーメッセージをチェックします。
- パーミッションの問題: 実行ファイルやディレクトリのパーミッションが適切か確認します。
サービスが自動起動しない場合
linger 設定の確認: loginctl show-user username | grep Linger で linger 設定が有効になっているか確認します。
感想
恥ずかしながらユーザーレベルでユニットファイルを管理できることを知らず、sudoers に特定ユーザーの systemctl コマンドを許可するなどして対応していました。
そんな時、Capistranoの設定で /bin/systemctl --user restart myservice.service というコマンドを見かけたのです!
--user とついているだけあって、ユーザー固有のものでは?と調べてみると大正解。
知らなかったー!恥ずかしい!
ただ実際に設定してみると、linger 設定の必要性を知らなかったため、環境構築後にサービスが定期的に停止してしまい、ちょっと躓いたり。
しかし今後はこの機能を積極的に活用していく予定です。
まとめ
ユーザー固有の systemd ユニットファイルを利用することで、より細かいサービス管理が可能になります。
特に複数ユーザーが利用するシステムでは、各ユーザーが独自のサービスを管理できるメリットがあります。
この記事が、ユーザー固有のサービス管理に役立つ参考資料となれば幸いです。