サーバーの再起動やミドルウェアの再起動を、 手作業で何度も繰り返す 必要が出てくる場面があります。 1台だけならまだしも、ミラーサーバーや複数台構成になってくると、同じ操作を台数分だけ繰り返すのは現実的ではありません。
- 作業時間がかかる
- 操作ミスが起きやすい
- 精神的にも地味に消耗する
この記事が向いているのは、次のようなケースです。
- 自分が管理している Linux サーバーで、同じ再起動作業を何度も繰り返している
rootパスワードをスクリプトに埋め込まずに、手元の負担だけ減らしたい- nginx の再起動手順を、毎回同じ形で安全寄りに実行したい
逆に、第三者が管理する共有サーバーや、本番で慎重な承認フローが必要な環境では、そのまま流用せず運用ルールに合わせてください。
そこで今回は、
「リモートサーバーに接続し、root 権限で nginx を安全に再起動するまで」
という一連の流れを、できる限り自動化できないかを考えてみました。
先に結論
この方法のポイントは、危険なところだけ人が握り、定型処理だけを機械に任せる ことです。
- SSH ログインは手動
su - rootのパスワード入力も手動- nginx の停止確認、待機、再起動だけ自動
完全自動化より地味ですが、安全性と省力化のバランスが取りやすい のが利点です。
やりたいことの流れ
今回自動化したい処理は、次のようなステップです。
homepageユーザーで SSH 接続 (※ パスワード入力が必要)rootユーザーに切り替え (※ パスワード入力が必要)- nginx を停止
- nginx プロセスが完全に終了するまで待機
- nginx を起動
完全な自動化を目指すなら、sshpass や expect を使ってパスワード入力まで含める方法もあります。
しかしそれらは追加ツールの導入が必要で、 パスワードをスクリプトに持たせるリスク も無視できません。
そこで今回は、
- SSH と su のパスワード入力だけは手動
- それ以外の処理はすべて自動
という、現実的で安全寄りな落としどころを選びました。 多少不格好ではありますが、それでも作業負荷は大幅に減らせます。
実際に作ったシェルスクリプト
以下が今回完成したスクリプトです。
SSH 接続後、su - root のパスワードを手動入力するだけで、nginx の安全な再起動まで一気に実行できます。
#!/usr/bin/env bash
set -euo pipefail
# リモートサーバーへSSH接続して、root権限で nginx を安全に再起動するスクリプト
# - 停止後、nginxプロセスが完全に終了したことを確認してから起動する
# - systemd(systemctl) 環境と SysV(service) 環境の両方に対応
HOST="xxxxxxxxxxxxx" # 対象サーバーのホスト名(またはIP)
USER="xxxx" # SSHログインユーザー(接続先で su により root へ昇格できること)
# -tt: 疑似TTYを強制割り当て(su のパスワード入力を手動で行うために必要)
# ここで SSH ログイン後、su のパスワード入力が求められる
ssh -tt "${USER}@${HOST}" 'su - root -c "
set -euo pipefail
# ----------------------------
# 1) nginx を停止する
# - systemctl が使える環境では systemctl を優先
# - そうでない場合は service コマンドで停止する
# ----------------------------
if command -v systemctl >/dev/null 2>&1; then
systemctl stop nginx
# stop後に active でなければOK(念のため失敗扱いにしない)
systemctl is-active --quiet nginx || true
else
# service 側は戻り値が不安定な環境もあるので || true で握りつぶす
service nginx stop || true
fi
# ----------------------------
# 2) nginx プロセスが完全に消えるまで待つ
# - 最大 60 回(0.2秒×60=約12秒)チェックする
# ----------------------------
for i in \$(seq 1 60); do
# nginx がいなければ終了
pgrep -x nginx >/dev/null 2>&1 || break
sleep 0.2
done
# まだ残っていたらエラー終了(プロセス一覧も表示して原因調査しやすくする)
pgrep -x nginx >/dev/null 2>&1 && {
echo \"nginx still running\"
ps -ef | grep -E \"[n]ginx\"
exit 1
}
# ----------------------------
# 3) nginx を起動する
# - systemctl が使える環境では systemctl を優先
# - 起動後、active であることを確認する
# ----------------------------
if command -v systemctl >/dev/null 2>&1; then
systemctl start nginx
systemctl is-active --quiet nginx
else
service nginx start
fi
# 成功メッセージ
echo \"nginx restarted: OK\"
"'
プロセス監視の肝は、次の1行です。
pgrep -x nginx >/dev/null 2>&1 || break
pgrep は プロセスが存在すれば終了コード 0、存在しなければ 1 を返します。
出力は /dev/null に捨てていますが、 終了コードだけを判定材料として使っている のがポイントです。
これにより「nginx が消えるまで待つ」という処理を、非常にシンプルに書けています。
おわりに
完全自動化ではありませんが、
- 手作業の繰り返しを減らせる
- ミスを防げる
- 心理的な負担がかなり軽くなる
という点で、十分に実用的な仕組みになりました。 「全部自動にしないと意味がない」と思い込まず、 安全と効率のバランス を取るのも大事だなと感じた一件でした。