systemd におけるサービス管理の核心は .service ユニットファイルにあります。この設定ファイルは、プロセスの起動方法、ライフサイクル制御、依存関係、リソース制限などを宣言的に定義します。以下に、実践で最も頻繁に使用される構成要素を再構成・要約し、誤解を招きやすいポイントを明確に解説します。
基本構造
すべてのサービスファイルは以下の3つのセクションから構成されます:
[Unit]:ユニットのメタデータと他のユニットとの依存関係(例:After=network.target,Wants=redis.service)[Service]:実行ロジックの本体(Type,ExecStart,Restartなど)[Install]:有効化時の振る舞い(WantedBy=multi-user.target)
重要な Type 値の選択基準
Type= はサービスの起動モデルを決定する最重要パラメータです。用途に応じて以下のいずれかを選択します:
| Type | 適用ケース | 注意点 |
|---|---|---|
simple(デフォルト) |
長時間実行されるが、初期化完了を通知しないアプリケーション(例:静的Webサーバ) | 起動直後に「アクティブ」と判断されるため、IPCチャネルが準備できていない場合に依存サービスが失敗する可能性あり |
notify |
systemd へ初期化完了を明示的に通知できるサービス(C/Go/Python で sd_notify("READY=1") を実装) |
NotifyAccess=main を併記推奨。非対応アプリには利用不可 |
forking |
従来型のUNIXデーモン(fork() 後、親プロセスが即座に終了) |
PIDFile= の指定が強く推奨。未指定時は systemd がPIDを推定するため信頼性が低下 |
dbus |
D-Bus システムバス上で名前を取得するサービス | BusName=org.example.MyService を必須指定。自動的に dbus.socket への依存が追加される |
oneshot |
起動時に一度だけ実行して終了するスクリプト(例:初期化処理、クリーンアップ) | RemainAfterExit=yes を併用すると、実行後も「アクティブ」状態を維持可能 |
実行制御のキーオプション
以下の設定は、サービスの可用性と信頼性を左右します:
ExecStart=:メイン実行コマンド。絶対パス推奨(例:/usr/local/bin/myapp --config /etc/myapp.conf)ExecStartPre=:起動前に実行(例:ディレクトリ作成、権限チェック)。失敗時は起動中止ExecStop=:停止時に実行。非同期なシグナル送信(kill -TERM $MAINPID)ではなく、同期的な終了待機が必須(例:timeout 30s /usr/bin/myappctl shutdown)Restart=on-failure:障害発生時の自動復旧に最適。ただし、StartLimitIntervalSec=とStartLimitBurst=で再起動頻度を制限することTimeoutStartSec=60:起動タイムアウト。特にType=notifyの場合は、初期化遅延に対応するため必要
環境変数とコマンド構文の注意点
コマンドラインではシェル構文(パイプ・リダイレクト・バックグラウンド実行)は一切サポートされません。必要な場合は明示的にシェルを呼び出します:
# ✅ 正しい(sh 経由でパイプ実行)
ExecStart=/bin/sh -c 'journalctl -u nginx | grep "error" | wc -l'
# ❌ 間違い(systemd が解釈できない)
ExecStart=journalctl -u nginx | grep "error"
環境変数展開には2種類があります:
$VAR:空白区切りで複数引数に分割(例:Environment="ARGS=--debug --port 8080"→$ARGSは3つの引数になる)${VAR}:そのまま1つの引数として扱われる(例:${ARGS}は1つの引数--debug --port 8080)
実践サンプル:安全な oneshot サービス
システム起動時に一度だけ実行し、その後も「有効」と認識させたいケース:
[Unit]
Description=Initialize database schema
After=postgresql.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/db-migrate --env production
ExecStop=/usr/local/bin/db-rollback --env production
SuccessExitStatus=0 2
[Install]
WantedBy=multi-user.target
この設定では、systemctl start db-init.service を実行するとマイグレーションが走り、その後は「アクティブ」状態が維持されるため、再度実行しても無視されます。
リソース制御と監視の拡張
信頼性向上のため、以下の高度な機能も活用できます:
WatchdogSec=30:30秒ごとにsd_notify("WATCHDOG=1")を要求。応答がないと自動再起動MemoryMax=512M:cgroup v2 によるメモリ上限(systemd.resource-control(5)参照)OOMPolicy=stop:OOM 発生時にサービス全体をクリーンに停止
設定変更後は必ず検証を行います:sudo systemctl daemon-reload && sudo systemctl cat myapp.service で構文エラーを確認し、sudo systemctl verify myapp.service で整合性をチェックしてください。