Dockerコンテナがすぐ終了してしまう現象とは?
Dockerを使い始めたばかりの方が最初につまずきやすいのが、コンテナを起動してもすぐに止まってしまうという現象です。
docker ps でコンテナ一覧を確認しても何も表示されず、docker ps -a を実行すると以下のように「Exited」と表示されている――そんな経験はありませんか?
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1b2c3d4e5f6 ubuntu "/bin/bash" 10 seconds ago Exited (0) 8 seconds ago my-container
「コンテナがすぐ落ちる」「動かない」と感じる原因はいくつかのパターンに分類できます。この記事では、代表的な原因と具体的な解決策をコード例付きで解説します。
原因1:フォアグラウンドプロセスがない(Exited (0))
なぜ終了するのか
Dockerコンテナは、メインプロセス(PID 1)が終了するとコンテナ自体も終了する仕組みです。これはコンテナのライフサイクルにおける最も基本的なルールです。詳しくはコンテナのライフサイクルの記事で解説しています。
たとえば以下のコマンドでUbuntuコンテナを起動した場合、デフォルトのコマンド(/bin/bash)は入力を受け付ける端末がないため即座に終了します。
$ docker run ubuntu
# → 何も表示されず、すぐにプロンプトに戻る
docker ps -a で確認すると Exited (0) と表示されます。終了コード 0 は「正常終了」を意味するため、エラーではなく「やることがなくなったから終了した」という状態です。
解決策
方法1:-it オプションで対話モードにする
コンテナ内で対話的に操作したい場合は、-it オプションを付けて起動します。-i は標準入力を開いたままにし、-t は疑似端末を割り当てます。
$ docker run -it ubuntu /bin/bash
root@a1b2c3d4e5f6:/#
これでコンテナ内のシェルに入り、操作できるようになります。docker run -it の詳しい使い方はこちらの記事を参照してください。
方法2:-d オプション + 常駐プロセスでバックグラウンド実行する
Webサーバーなどを動かす場合は、-d(デタッチモード)で起動します。ただし、コンテナ内でフォアグラウンドで動き続けるプロセスが必要です。
# Nginxはフォアグラウンドで動くため、コンテナが維持される
$ docker run -d --name web nginx
# 起動確認
$ docker ps
CONTAINER ID IMAGE COMMAND STATUS PORTS NAMES
b2c3d4e5f6a7 nginx "/docker-entrypoint.…" Up 5 seconds 80/tcp web
docker run -d についてはdocker run -d の記事で詳しく解説しています。
💡 補足:単にコンテナを起動し続けたいだけなら、以下のように tail -f /dev/null を実行させる方法もあります。
$ docker run -d ubuntu tail -f /dev/null
原因2:コマンドやスクリプトにエラーがある(Exited (1) / Exited (2))
なぜ終了するのか
コンテナ起動時に指定したコマンドやDockerfileの CMD / ENTRYPOINT で実行されるスクリプトにエラーがあると、コンテナはすぐに終了します。このとき Exited (1) や Exited (2) のようにゼロ以外の終了コードが表示されます。
$ docker run ubuntu cat /nonexistent-file
cat: /nonexistent-file: No such file or directory
$ docker ps -a
CONTAINER ID IMAGE COMMAND STATUS NAMES
c3d4e5f6a7b8 ubuntu "cat /nonexistent-fi…" Exited (1) 2 seconds ago bold_pike
解決策
手順1:ログを確認する
docker logs コマンドでコンテナの出力を確認し、エラーの原因を特定します。
$ docker logs c3d4e5f6a7b8
cat: /nonexistent-file: No such file or directory
手順2:コマンドを修正して再実行する
エラー内容を確認したら、正しいコマンドやパスに修正して再度実行します。
# 正しいファイルパスに修正
$ docker run ubuntu cat /etc/os-release
⚠️ 注意:Dockerfileの CMD や ENTRYPOINT に記述されたコマンドが原因の場合は、Dockerfileを修正してイメージを再ビルドする必要があります。
原因3:Dockerfileの CMD / ENTRYPOINT の記述ミス
なぜ終了するのか
Dockerfileで CMD や ENTRYPOINT の書き方を間違えると、意図したプロセスが起動せずにコンテナがすぐ終了します。よくあるミスを以下にまとめます。
| ミスの内容 | 例 | 問題点 |
|---|---|---|
| コマンドのパスが間違っている | CMD ["/usr/bin/myap"] |
ファイルが見つからずエラー終了 |
| シェル形式とexec形式の混同 | ENTRYPOINT /app/start.sh |
シェル形式だとシグナル処理に問題が出る場合がある |
| 実行権限がない | CMD ["./start.sh"] |
permission denied で終了 |
解決策
手順1:コンテナに入ってデバッグする
エントリポイントを上書きしてコンテナに入り、問題を調査します。
# エントリポイントを /bin/bash に上書きして対話シェルに入る
$ docker run -it --entrypoint /bin/bash my-image
# コンテナ内でスクリプトの存在と権限を確認
root@container:/# ls -la /app/start.sh
root@container:/# cat /app/start.sh
手順2:Dockerfileを修正する
# 修正前(権限なし)
COPY start.sh /app/start.sh
CMD ["./app/start.sh"]
# 修正後(実行権限を付与 + パスを正しく指定)
COPY start.sh /app/start.sh
RUN chmod +x /app/start.sh
CMD ["/app/start.sh"]
修正後はイメージを再ビルドします。
$ docker build -t my-image .
$ docker run -d my-image
原因4:依存サービスの起動前にアプリが接続を試みている(Exited (1))
なぜ終了するのか
Docker Composeで複数のコンテナを連携させる場合、アプリケーションコンテナがデータベースなどの依存サービスより先に起動し、接続に失敗してすぐ終了するケースがあります。
$ docker compose up
db_1 | Initializing database...
app_1 | Error: connect ECONNREFUSED 172.18.0.2:5432
app_1 exited with code 1
depends_on を設定していても、これは「起動順序」を保証するだけで「依存サービスが準備完了している」ことは保証しません。
解決策
方法1:depends_on に condition を指定する(Docker Compose v2)
services:
db:
image: postgres:15
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
app:
build: .
depends_on:
db:
condition: service_healthy
方法2:アプリ側でリトライロジックを入れる
エントリポイントのスクリプトで、データベースが応答するまで待つ処理を追加します。
#!/bin/bash
# wait-for-db.sh
echo "Waiting for database..."
until pg_isready -h db -U postgres; do
sleep 2
done
echo "Database is ready!"
exec "$@"
原因5:メモリ不足でプロセスが強制終了される(Exited (137))
なぜ終了するのか
終了コード 137 は、プロセスが SIGKILL(シグナル番号9)によって強制終了されたことを示します(128 + 9 = 137)。多くの場合、コンテナに割り当てられたメモリの上限を超えた(OOM: Out Of Memory)ことが原因です。
$ docker ps -a
CONTAINER ID IMAGE STATUS NAMES
d4e5f6a7b8c9 my-app Exited (137) 5 seconds ago my-app
解決策
手順1:メモリ制限を確認する
# コンテナのメモリ使用状況を確認
$ docker stats --no-stream
# メモリ制限の詳細を確認
$ docker inspect my-app | grep -i memory
手順2:メモリ制限を緩和する
# メモリ上限を増やして起動
$ docker run -d --memory=512m --name my-app my-image
# Docker Composeの場合
services:
app:
image: my-image
deploy:
resources:
limits:
memory: 512M
💡 補足:根本的には、アプリケーション自体のメモリ使用量を最適化することも重要です。例えばJavaアプリであれば -Xmx オプションでヒープサイズを適切に設定しましょう。
デバッグに役立つコマンドまとめ
コンテナがすぐ終了する問題を調査するとき、以下のコマンドが役立ちます。Docker主要コマンドの一覧はこちらの記事も参考にしてください。
| コマンド | 用途 |
|---|---|
docker ps -a |
停止中のコンテナも含めて一覧表示。STATUS欄で終了コードを確認 |
docker logs コンテナ名 |
コンテナの標準出力・標準エラー出力を確認 |
docker inspect コンテナ名 |
コンテナの詳細設定(メモリ制限、環境変数など)を確認 |
docker run -it --entrypoint /bin/bash イメージ名 |
エントリポイントを上書きしてコンテナ内を調査 |
docker stats |
実行中コンテナのCPU・メモリ使用状況をリアルタイム表示 |
まとめ
Dockerコンテナがすぐ終了(Exited)する主な原因と対処法を振り返ります。
- ✅ Exited (0):フォアグラウンドプロセスがない →
-itや-dオプション、常駐プロセスの指定で解決 - ✅ Exited (1) / Exited (2):コマンドやスクリプトのエラー →
docker logsで原因を確認して修正 - ✅ Exited (1) + 依存サービス:接続先が未準備 → ヘルスチェックやリトライロジックで対応
- ✅ Exited (137):メモリ不足(OOM Kill) → メモリ制限の見直しやアプリの最適化
- ✅ 共通の調査手順:まず
docker ps -aで終了コードを確認し、docker logsで詳細を調べる
コンテナがすぐ止まる・すぐ落ちるときは、まず終了コードの数字を確認するところから始めましょう。終了コードがわかれば、この記事で紹介した対処法で多くのケースを解決できます。



コメント