ExecStartPre / ExecStartPost の実務活用例【systemd実践テクニック】

  • URLをコピーしました!

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障害の予防・再発防止に非常に強力な武器になります。

目次