🐧 Linux 総合学習プラットフォーム
プロセス監視/障害対応 ・ 中級

サービスが起動しない・落ちるとき

systemdサービスが起動に失敗したり、動いていたはずが落ちていたりするときは、systemctl status で状態と直近ログを見るのが最初の一手です。journalctl -u で過去にさかのぼり、exit codeやRestart設定によるループの有無を確認します。設定ミス・ポート衝突・権限・依存先落ちという4大原因を押さえれば、原因の見当が速く付きます。

「systemctl start で起動したはずのサービスが、いつの間にか止まっている」「デプロイ後、アプリにアクセスできない」――systemd管理下のサービスにまつわる障害は、運用でもっとも頻繁に出会う種類の1つだ。

幸い、systemdはサービスの状態や直近のログを1コマンドで教えてくれる。落ち着いて手順を踏めば、原因の見当は驚くほど速く付く。

🩺 まず systemctl status で聞診する

最初の一手は systemctl status サービス名 だ。医者が聴診器を当てるように、サービスの今の状態をひと目で確認できる。

systemctl status nginx ……Active の行に running/failed/inactive などの状態が出て、その下に直近の数行のログが自動で表示される。多くの場合、ここに原因の手がかりが載っている。

表示される情報は多いが、着目すべきは主に3つ。Active 行の状態、Main PID の有無、そして下部に表示される直近ログの内容だ。failed になっていれば起動に失敗しており、その理由の断片がログ欄に出ていることが多い。

💡
ポイントsystemctl status は「今どうなっているか」と「直近何が起きたか」を1画面でまとめて見せてくれる。障害調査は必ずここから始める。
● nginx.service - A high performance web server Active: failed (Result: exit-code)Jun 27 09:12 nginx[812]: [emerg] bind() to 0.0.0.0:80 failedJun 27 09:12 systemd[1]: nginx.service: Failed with result exit-codeActive: failed で失敗確認直近ログでbind失敗と判明

📜 journalctl -u -e で過去へさかのぼる

status に出るログは直近の数行だけなので、経緯を追うにはもっと過去までさかのぼりたい。そこで使うのが journalctl -u サービス名 -e だ。

journalctl -u nginx -e ……そのサービスに関するログだけを、末尾(最新)から表示する。-e は end を意味し、大量のログの最後にジャンプしてくれる。

これで「いつから調子が悪くなったか」「再起動を何度も試みているか」「特定のエラーが繰り返し出ていないか」を時系列で追える。--since '1 hour ago' のように時間を指定して絞り込むのも有効だ。

🔢 exit codeとRestart=によるループ

ログの中には exit code(終了コード)が記録されている。これはプロセスが「なぜ終了したか」を表す数値で、0なら正常終了、それ以外は何らかの異常を意味する。

systemctl status の出力にも Main PID の行の近くに「(code=exited, status=1/FAILURE)」のように exit code が表示される。数値そのものの意味はアプリごとに異なるが、「0か非0か」だけでも起動失敗の事実を機械的に確認できる。

systemdのユニット設定には Restart= という項目があり、on-failure などに設定されていると、サービスが落ちるたびに自動で再起動を試みる。これは可用性を高める良い機能だが、原因が解消していないと「起動→即失敗→再起動→即失敗」を延々と繰り返す再起動ループに陥る。

つまずき再起動ループの最中は、journalctl の画面に同じようなエラーが何度も流れ続ける。これを見たら、まず systemctl stop で自動再起動を止めてから、落ち着いて原因を調べたほうがよい。ループしたまま調査すると、ログが流れて追いにくい。
起動即失敗 exit≠0Restart=自動で再起動原因が解消しない限り、この輪をぐるぐる回り続ける

🧯 4大原因を型として押さえる

exit codeやログの内容が読めたら、原因を絞り込む。サービス起動失敗の原因は、実務上ほぼ次の4パターンに集約される。

1つ目は設定ミスだ。設定ファイルの構文エラーが典型で、多くのミドルウェアには構文だけをチェックする機能が用意されている。nginxなら nginx -t、Apacheなら apachectl configtest のように、実際に再起動する前に構文の妥当性だけを確認できる。

nginx -t ……実際には起動・再起動せず、設定ファイルの構文が正しいかどうかだけを検証する。「syntax is ok」と出れば設定ファイル自体は壊れていない。
コツsystemctl restart の前に、対象サービスに構文チェック系のサブコマンドがないか確認する習慣を付けると、設定ミスによる再起動ループを未然に防げる。

2つ目はポート衝突だ。すでに別のプロセスが同じポートを使っていると、後から起動しようとしたサービスは待ち受けに失敗する。先ほどのSVGの例のように bind() failed と出ていたら、まずこれを疑う。ss -tlnp や lsof -i :ポート番号 で、そのポートをすでに誰が使っているかを確認できる。

3つ目は権限だ。設定ファイルや証明書、ソケットファイルなどにサービス実行ユーザーがアクセスできる権限がないと、起動時にPermission deniedで失敗する。ファイルの所有者・パーミッションを確認する。

ls -l /etc/ssl/private/app.key ……対象ファイルの所有者とパーミッションを表示する。サービスを動かしているユーザーがそのファイルを読めるか(所有者一致・グループ一致・その他への許可のいずれか)を目で確認できる。

4つ目は依存先落ちだ。データベースに接続できないと起動しないアプリのように、そのサービスが依存する別のサービスやリソースが先に落ちていることがある。systemdのユニット定義には依存関係(After=やRequires=)を書けるが、依存先自体が正常に動いているかは別途確認が必要になる。

コツ依存先を疑ったら、まず systemctl status 依存先サービス名 で、その依存先自体が動いているかを確認する。原因が芋づる式に連鎖していることもあるので、1つ直して終わりにせず全体を通しで見る。
🔗
たとえ4大原因は、家の電気がつかないときの定番チェックリストに似ている。ブレーカーは落ちていないか(依存先)、電球は合っているか(設定)、コンセントは塞がれていないか(ポート衝突)、スイッチに鍵がかかっていないか(権限)――順に当てはめていくと早い。

💾 restartの前に、ログを保存する習慣

原因調査の途中で systemctl restart を実行すると、それまでの状態を示す直近ログが上書きされてしまい、貴重な手がかりを失うことがある。

コツ深追いする前に journalctl -u サービス名 --since '1 hour ago' > /tmp/svc-before-restart.log のように、現状のログをファイルへ保存しておく。後から見返せる証拠が残り、再現待ちにもならずに済む。

systemctl status で状態を掴み、journalctl -u -e で経緯を追い、exit codeとRestart=の動きを読み、4大原因に当てはめる――この流れを型として持っておくと、深夜のアラートにも落ち着いて対応できるようになる。

この項目に出てくる用語

終了コード(exit code)しゅうりょうこーど
プロセスが終了したときにOSへ返す数値。0は正常、それ以外は異常終了を示す。
再起動ループさいきどうるーぷ
原因が解消しないまま自動再起動を繰り返し続けるサービスの状態。

▶ 学習アプリでこの続きを学ぶ・演習する