systemd の unit ファイルには多くのディレクティブがありますが、 ExecStartPre / ExecStartPost は 「知っているかどうか」で運用レベルに大きな差が出る項目です。
本記事では、
- ExecStartPre / ExecStartPost の正しい役割
- 実務でよく使われる具体例
- やりがちな事故・アンチパターン
を障害対応・運用視点で解説します。
目次
ExecStartPre / ExecStartPost とは
基本構文
[Service]
ExecStartPre=コマンド
ExecStart=メイン起動コマンド
ExecStartPost=コマンド
実行タイミング
- ExecStartPre:ExecStart の直前
- ExecStartPost:ExecStart が成功した後
重要なのは、ExecStart が成功しなければ ExecStartPost は実行されない という点です。
ExecStartPre の実務活用例
① 起動前の環境チェック
ポート競合や前回の異常終了を検知する用途は非常に多いです。
[Service]
ExecStartPre=/usr/bin/ss -lnt | grep -q ':8080' && exit 1 || exit 0
ExecStart=/usr/local/bin/myservice
→ ポートが使用中なら起動を失敗させる
② 古いPIDFile・ロックファイルの削除
PIDFile残骸による起動失敗対策として定番です。
[Service]
ExecStartPre=/usr/bin/rm -f /run/myservice.pid
ExecStart=/usr/local/bin/myservice
systemdで PIDFile 問題が多い環境ではほぼ必須です。
③ ディレクトリ・ファイルの事前作成
アプリが起動時に必要とするパスを先に用意します。
[Service]
ExecStartPre=/usr/bin/mkdir -p /var/log/myservice
ExecStartPre=/usr/bin/chown myuser:myuser /var/log/myservice
ExecStart=/usr/local/bin/myservice
※ RuntimeDirectory が使えない場合の代替策
④ 設定ファイルの検証
設定ミスでの起動事故を未然に防ぐ重要パターンです。
[Service]
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
→ 設定エラーなら起動自体を止める
ExecStartPost の実務活用例
① 起動後の通知・ログ出力
[Service]
ExecStart=/usr/local/bin/myservice
ExecStartPost=/usr/bin/logger "myservice started successfully"
起動成功の可視化に有効です。
② PIDFile / 状態ファイルの調整
デーモン側で制御できない場合の補助として使われます。
[Service]
ExecStart=/usr/local/bin/myservice
ExecStartPost=/usr/bin/chmod 644 /run/myservice.pid
③ 起動後の依存サービス操作
強くは推奨されませんが、現場ではよく見かけます。
[Service]
ExecStart=/usr/local/bin/myservice
ExecStartPost=/usr/bin/systemctl reload apache2
依存関係は Requires / After を使うのが原則です。
失敗しやすいアンチパターン
① ExecStartPre で重い処理をする
- DBマイグレーション
- 大量データコピー
→ 起動が遅くなり、TimeoutStartSec 超過を招く
② ExecStartPost に失敗してサービス全体が失敗する
ExecStartPost が失敗すると、サービス全体が failed 扱いになります。
対策
ExecStartPost=-/usr/bin/false
先頭の - は失敗を無視します。
③ ExecStartPre を複雑なスクリプトにする
切り分けが困難になります。
- できるだけ単一コマンド
- 複雑なら外部スクリプト化
複数指定時の挙動(重要)
ExecStartPre=/bin/echo pre1
ExecStartPre=/bin/echo pre2
- 上から順に実行
- 1つでも失敗すると ExecStart は実行されない
ExecStartPre/Post と Restart の関係
Restart=on-failure が設定されている場合:
- 再起動時にも ExecStartPre は毎回実行される
- ExecStartPost は起動成功時のみ
再起動ループ時の副作用には注意が必要です。
実務で使える安全テンプレート
[Service]
Type=simple
User=myuser
ExecStartPre=/usr/bin/rm -f /run/myservice.pid
ExecStartPre=/usr/bin/test -f /etc/myservice.conf
ExecStart=/usr/local/bin/myservice
ExecStartPost=/usr/bin/logger "myservice started"
Restart=on-failure
TimeoutStartSec=30
まとめ
- ExecStartPre は「起動前の安全装置」
- ExecStartPost は「起動成功後の後処理」
- 失敗=サービス失敗になる点を常に意識
正しく使えば、 systemd障害の予防・再発防止に非常に強力な武器になります。
あわせて読みたい


systemd Restart設定のベストプラクティス【再起動ループを防ぐ設計指針】
systemdの Restart 設定は、サービスの可用性を高める一方で、 設定を誤ると再起動ループや障害の長期化を引き起こす非常に危険な項目です。 本記事では、実務で頻発す…
あわせて読みたい


systemd unitファイルの書き方完全テンプレ|実務で使える設定例付き
systemdのunitファイルは「なんとなく動く設定」と「事故らない設定」に大きな差があります。 本記事では、 最低限の構成 実務で必須の推奨設定 Type別テンプレ 障害を…
あわせて読みたい


systemd サービスが自動起動しない/Enable されないときの原因と対処
Linux サーバーでは systemd によるサービスの自動起動設定が広く利用されています。しかし、意図したサービスが再起動後に自動で立ち上がらない、あるいは systemctl e…
