ホーム › 記事一覧 › Dockerコンテナが Restarting を繰り返す:logs・inspect・起動コマンドを見る順番

Docker

Dockerコンテナが Restarting を繰り返す:logs・inspect・起動コマンドを見る順番

公開 2026-10-26読了 5 分

Photo: Wolfgang Weiser / Pexels

この記事でわかること
docker ps で Restarting が続くコンテナを、logs・inspect の終了コード・起動コマンドの順に確認して原因を絞り込む手順を整理します。よくある原因別の直し方もまとめました。

先に結論です。docker ps で Restarting が続くときは、コンテナの中で動くはずのプロセスがすぐ終わり、再起動ポリシー(restart: always や unless-stopped)がそれを起こし直している状態です。原因は Docker 本体ではなく、ほとんどが 中のアプリが起動直後に終了している理由 にあります。次の順番で見ると、闇雲に作り直すより早く原因に届きます。

  1. docker logs でアプリ自身のエラーを読む
  2. docker inspect で終了コードと OOM の有無を見る
  3. 起動コマンド・マウント・環境変数を確認する

まず状態を確認する

docker ps -a

STATUS 列に Restarting (1) 10 seconds ago のように表示されます。カッコ内の数字は 直前に終了したときの終了コード です。この数字が原因の手がかりになるので、メモしておきます。

Docker Compose で動かしている場合は、次のコマンドでも同じ情報が見られます。

docker compose ps -a

手順1:docker logs でアプリのエラーを読む

いちばん情報が多いのはログです。再起動を繰り返していても、直前までのログは読めます。

docker logs --tail 50 <コンテナ名>
# Compose の場合
docker compose logs --tail 50 <サービス名>

見るのは最後の数行です。Permission denied、No such file or directory、connection refused、missing required environment variable のような一文が出ていれば、それがほぼ答えです。

ログが空のまま再起動している場合は、アプリが何も出力する前に終わっています。その場合は次の inspect に進みます。

手順2:docker inspect で終了コードを見る

docker inspect --format 'ExitCode={{.State.ExitCode}} OOMKilled={{.State.OOMKilled}} Restarts={{.RestartCount}} Error={{.State.Error}}' <コンテナ名>

終了コードは、一般に次のように読むとされています。

終了コードよくある意味次に見るところ
0正常終了した(常駐しないコマンドだった)起動コマンド
1アプリが自分でエラー終了したログ・設定ファイル
126コマンドに実行権限がないスクリプトの権限
127コマンドが見つからないcommand: の書き間違い
137強制終了(SIGKILL)。OOMKilled=true ならメモリ不足メモリ上限・ホストの空きメモリ
139セグメンテーション違反イメージのアーキテクチャ・バージョン

終了コード 0 で Restarting は見落としやすいパターンです。アプリは正常に終わっているのに、restart: always が付いているので起こし直され続けています。一度だけ実行するタスク用のイメージを常駐サービスとして書いてしまったときなどに起こります。

137 で OOMKilled=true なら、コンテナのメモリ上限(mem_limit など)か、ホスト全体のメモリが足りていません。free -h でホストの空きを確認し、上限を上げるか、同時に動かすコンテナを減らします。ミニPC で多くのサービスを動かしていて常にメモリが厳しいなら、増設できる機種であればメモリを足すのも手です。

手順3:起動コマンド・マウント・環境変数を見る

ログと終了コードで当たりがついたら、設定側を確認します。まず、Compose ファイルが意図どおりに解釈されているかを見ます。

docker compose config

変数の展開後の内容が表示されるので、.env の値が空になっていないか、パスがずれていないかを確認できます。

よくある原因と直し方

  • 設定ファイルのはずがディレクトリになっている:バインドマウントでホスト側のパスが存在しないと、Docker はそこに空のディレクトリを作ります。./config.yml:/app/config.yml のつもりが、ホストに config.yml という名前のフォルダができていたら、それが原因です。フォルダを消して、正しいファイルを置いてから起動し直します
  • 権限が足りない:マウントしたフォルダの所有者と、コンテナ内のユーザー(PUID / PGID など)が合っていないと、書き込みで失敗して終了します。ls -ln でホスト側の UID・GID を確認します
  • 必須の環境変数がない:DB のパスワードや管理者ユーザー名を必須にしているイメージは多いです。イメージの説明ページで必須の変数を確認します
  • 依存先が起動前に接続しに行っている:アプリが DB より先に起動して接続に失敗するケースです。depends_on に condition: service_healthy を付け、DB 側に healthcheck を書くと順番を待たせられます
  • アーキテクチャが違う:ラズパイ(arm64)で amd64 専用のイメージを動かすと exec format error で終わります。イメージが arm64 に対応しているか確認します

再起動ループを止めて中を調べる

再起動が速すぎて調べにくいときは、いったん再起動ポリシーを外します。

docker update --restart=no <コンテナ名>

そのうえで、起動コマンドを差し替えてシェルで入ると、マウントされたファイルや権限をコンテナの中から確認できます。

docker compose run --rm --entrypoint sh <サービス名>

中で ls -l や id を実行し、アプリが読むファイルが見えているか、書き込めるユーザーで動いているかを確かめます。原因を直したら、Compose ファイルの restart: は元のままなので、docker compose up -d --force-recreate <サービス名> で作り直せば元の再起動ポリシーに戻ります(docker update での変更は Compose からは差分として見えないため、--force-recreate を付けます)。

確認の順番まとめ

  • docker ps -a の STATUS で終了コードをメモした
  • docker logs --tail 50 で最後のエラーを読んだ
  • docker inspect で ExitCode・OOMKilled を見た
  • docker compose config で展開後の設定を確認した
  • 必要なら再起動を止めて、シェルで中を確認した

まとめ

  • Restarting は「中のプロセスがすぐ終わる」状態。Docker ではなくアプリ側の理由を探す
  • 見る順番は logs → inspect の終了コード → 起動コマンド・マウント・環境変数
  • 終了コード 0 は常駐しないコマンド、137 はメモリ不足を疑う
  • 調べにくいときは docker update --restart=no で止めて、シェルで中を確認する

運営者が作った Excel テンプレートを BOOTH で配布しています。IT 資産管理台帳(無料 Lite 版あり) / IT 資格の学習管理シート

部長(本業: IT インフラ) 家でも同じことをして遊んでいます。記事は実機で試してから書き、失敗もそのまま載せます。