言語を切り替える
テーマを切り替える

Dockerコンテナが起動しない?「Exit Code 1」などの原因を特定する4ステップ

金曜の夜8時半、帰り支度をしていた私のスマホが震えました。本番環境のアラートです。
確認すると、4つのコアサービスのコンテナがすべて「Exited」状態になっていました。
ターミナルを開き docker ps を叩くも、結果は空白。

背筋が凍る瞬間です。「週末が消えたな」と覚悟しました。

結局、2時間の調査の末に見つかった原因は、設定ファイルのパスミスという単純なものでした。もし当時の私が「体系的な調査フロー」を持っていれば、10分で解決できていたはずです。

この記事では、私が数々の失敗から学んだ「コンテナが起動しない時のトラブルシューティング手法」を共有します。Exit Code 1 や 137 を見たときに何をすべきか、もう迷うことはありません。

まず理解すべき:終了コード(Exit Code)の意味

コンテナが停止した時、Dockerは必ず「終了コード」を残します。これは死因を特定するダイイングメッセージです。

終了コード意味よくある原因
0正常終了バッチ処理が完了した、など(異常ではありません)。
1一般的なエラーアプリの設定ミス、バグ、例外発生など、最も多いケース。
137強制終了 (SIGKILL)メモリ不足 (OOM Killer) が大半。または docker kill された。
127コマンドが見つからないDockerfileのCMDやENTRYPOINTで指定したコマンドが存在しない。
139Segmentation Faultメモリアクセス違反。C/C++等の低レイヤーアプリで発生。
1-128アプリ内部のエラー設定ファイルミス、権限不足、DB接続失敗など。
129-255OSシグナルによる終了外部からの停止命令や強制終了。

特に Exit Code 137 は重要です。これは「メモリを使いすぎてLinuxカーネルに殺された」可能性が高いからです。

4ステップ排查法(トラブルシューティング・フロー)

ステップ1:コンテナの状態を確認する

まず、死んだコンテナを見つけます。docker ps では見えないので -a を付けます。

docker ps -a

出力例:

CONTAINER ID   IMAGE         STATUS
a1b2c3d4e5f6   mysql:8.0     Exited (1) 2 minutes ago

ここで STATUS 列の Exited (1) に注目。終了コードは1です。「アプリ内部で何か起きたな」と推測できます。

ステップ2:ログを見る(最重要)

ほぼ全ての答えはログにあります。

docker logs <container_id>

もしログが長すぎる場合は、直近100行だけ見ます:

docker logs --tail 100 <container_id>

エラーメッセージ(Error, Exception, Fatal など)を探してください。「Config file not found」や「Connection refused」があれば、それが答えです。

ステップ3:コンテナの設定を深掘りする (docker inspect)

ログを見ても分からない場合、コンテナの設定自体が間違っている可能性があります。docker inspect で詳細情報を見ます。

終了コードを見る:

docker inspect --format '{{.State.ExitCode}}' <container_id>

メモリ不足(OOM)で死んだか確認する:

docker inspect --format '{{.State.OOMKilled}}' <container_id>

これが true なら、メモリ不足が確定です。

マウントパスを確認する:

docker inspect --format '{{.Mounts}}' <container_id>

設定ファイルを置いたつもりの場所に、本当にマウントされていますか?

ステップ4:対話モードで手動起動してみる

上記でも分からない場合、コンテナの中に入って手動で動かしてみるのが確実です。

本来の起動コマンドが docker run -d my-app だとしたら、-d(バックグラウンド)の代わりに -it(対話モード)を使い、コマンドをシェル(/bin/bash/bin/sh)で上書きします。

docker run -it my-app /bin/bash

コンテナの中に入れたら、以下を試します:

  1. 設定ファイルはあるか? (ls -l /etc/my-app/config.yml)
  2. 依存サービス(DBなど)に繋がるか? (curl db:3306ping db)
  3. 手動でアプリを起動してみる (./start.shnode index.js)

これで、エラーが目の前で再現されるはずです。

よくある5つの失敗パターンと解決策

パターン1:設定ファイルパスの間違い(Exit 1)

症状:ログに No such file or directoryConfig not found
原因:ホスト側のパス、またはコンテナ側のマウント先パスを書き間違えている。

対策

# 間違い
docker run -v /host/conf:/app/config ... 
# 正解(アプリが期待しているのは /app/conf だった場合)
docker run -v /host/conf:/app/conf ...

パターン2:メモリ不足 (OOM Killed)(Exit 137)

症状:突然死ぬ。docker inspectOOMKilled: true になる。Linuxのシステムログ (dmesg) にも記録が残る。
原因:コンテナに割り当てたメモリ制限が厳しすぎるか、アプリがメモリリークしている。

対策

  • メモリ制限を増やす:docker run -m 1g ...
  • Javaの場合、ヒープサイズを指定する:-Xmx512m など。

パターン3:ポートの競合(Exit 1)

症状:ログに Address already in useBind for 0.0.0.0:80 failed
原因:そのポートを他のコンテナやホスト上のプロセス(Apache/Nginxなど)が既に使っている。

対策

  • 競合しているプロセスを止める。
  • マッピングするポートを変える:-p 8080:80(ホストの8080をコンテナの80に繋ぐ)。

パターン4:権限不足(Permission Denied)(Exit 1)

症状:ログに Permission deniedAccess denied
原因:コンテナ内のユーザー(非root)が、マウントされたホスト側のファイルを読み書きできない。

対策

  • ホスト側のファイルの所有者を変更する:chown
  • コンテナをrootで実行する(開発時のみ):--user root
  • コンテナ実行ユーザーとホストユーザーのUIDを合わせる。

パターン5:依存サービスが準備できていない

症状Connection refused。DBコンテナとアプリコンテナを同時に立ち上げたが、DBの起動が遅くてアプリが先に死ぬ。
原因:コンテナの起動順序制御が甘い。

対策

  • Docker Composedepends_oncondition: service_healthy を使う。
  • Waitスクリプトwait-for-it.sh などのスクリプトを使い、DBのポートが開くまで待機してからアプリを起動する。
# 起動コマンドの例
./wait-for-it.sh mysql:3306 -- node app.js

まとめ

コンテナが起動しないときは、パニックにならず、以下のリストをチェックしてください。

  1. docker ps -a で終了コードを見る。
  2. docker logs でエラーメッセージを読む。
  3. Exit 137 ならメモリを疑う。
  4. Exit 1 なら設定ミスか権限エラーを疑う。
  5. どうしても分からなければ -it /bin/bash で中に入って調査する。

このフローさえ頭に入っていれば、どんなエラーも論理的に解決できます。

Dockerコンテナ起動失敗の完全調査フロー

コンテナがExited状態になる原因を特定し、修復するための4ステップ

⏱️ Estimated time: 15 min

  1. 1

    Step1: ステップ1:状態コードの確認

    コマンド:docker ps -a
    解説:STATUS列を確認します。「Exited (1)」ならアプリのエラー、「Exited (137)」ならメモリ不足(OOM)の可能性が高いです。
  2. 2

    Step2: ステップ2:ログの分析

    コマンド:docker logs <container_id>
    解説:エラーメッセージを探します。ログが長すぎる場合は --tail 50 で直近のみを表示します。
  3. 3

    Step3: ステップ3:詳細設定の検査

    コマンド:docker inspect <container_id>
    解説:State.OOMKilledがtrueになっていないか、Mounts(マウントパス)が正しいかを確認します。
  4. 4

    Step4: ステップ4:手動起動による検証

    コマンド:docker run -it <image> /bin/bash
    解説:対話モードでコンテナ内に入り、手動でアプリを起動してエラーを再現させます。設定ファイルの存在確認やネットワーク疎通確認も行います。

FAQ

Exit Code 137とは何ですか?
コンテナが強制終了シグナル(SIGKILL)を受け取ったことを意味します。最も一般的な原因は「Out Of Memory (OOM) Killer」です。コンテナがメモリ制限を超えたため、Linuxカーネルによって強制停止させられた状態です。メモリ割り当てを増やすか、メモリリークを修正する必要があります。
docker logsを見ても何も表示されません。
コンテナが起動コマンド(CMD/ENTRYPOINT)の実行直前に失敗している可能性があります(例えばコマンドが見つからないExit 127など)。または、アプリがSTDOUT/STDERRではなくファイルにログを出力している設定かもしれません。`docker inspect`でログパスを確認するか、`-it`で手動起動して確認してください。
コンテナ起動直後にExited (0)になります。
Exit 0は「正常終了」です。フォアグラウンドで実行し続けるプロセスがない場合、コンテナは役割を終えたと判断して停止します。Webサーバーなどを動かす場合は、バックグラウンドに回らずフォアグラウンドで実行し続ける設定(例:nginxなら `Daemon off;`)が必要です。

3 min read · 公開日: 2025年12月18日 · 更新日: 2026年1月22日

コメント

GitHubアカウントでログインしてコメントできます

関連記事