- Docker
Docker Exited (137)の原因と直し方|OOMKilled
Exited (137) は、コンテナのメインのプロセスが、強制終了の信号(SIGKILL)で止められたことを表します。 137 は「128 + 9(SIGKILL の番号)」です。
137 は「メモリ不足」とよく説明されますが、確認環境では、メモリと関係なく 137 になる場合がありました。
| 原因 | OOMKilled |
見分け方 | 直し方 |
|---|---|---|---|
| メモリの上限を超えた | true | docker inspect |
上限を上げる、アプリの使うメモリを減らす |
docker stop で、10秒たっても止まらなかった |
false | docker stop に約10秒かかる |
終了の信号(SIGTERM)を受け取れるようにする(--init など) |
docker kill |
false | 自分で実行した | — |
| ホスト全体のメモリ不足 | 状況による | ホストの空きメモリ | ホストのメモリ・ほかのコンテナを確かめる |
確認環境:Docker Engine 29.4(Linux、cgroup v2)、Java 21(確認日 2026年10月11日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Docker Exited (137)の原因と直し方|OOMKilled」
まず確認:OOMKilled を見る
docker ps -a # STATUS が Exited (137)
docker inspect コンテナ名 --format 'exit={{.State.ExitCode}} OOMKilled={{.State.OOMKilled}}'
| 状況 | 結果(確認環境) |
|---|---|
メモリの上限(--memory 64m)を超えた |
exit=137 OOMKilled=true |
docker stop で止めた(信号を受け取れない) |
exit=137 OOMKilled=false |
docker kill で止めた |
exit=137 OOMKilled=false |
OOMKilled=true ならメモリ、false なら停止のしかたを疑います。docker ps -a の表示はどちらも同じ Exited (137) でした。
原因1:メモリの上限を超えた(OOMKilled=true)
$ docker run --name oom2 --memory 64m --memory-swap 64m bb:1 sh -c 'head -c 300000000 /dev/zero | tail'
Killed
$ echo $?
137
$ docker inspect oom2 --format '{{json .State}}'
"Status": "exited", "OOMKilled": true, "ExitCode": 137, "Error": ""
--memory で決めた上限を超えると、カーネルがプロセスを強制終了しました。 Error は空で、アプリのログにも何も残らないことが多いので、OOMKilled を見ないと原因が分かりません。
docker events --filter event=oom # 起きた瞬間に「oom」のイベントが出る
docker stats # 動いている間の使用量
1791654552 oom oom2
1791654552 die oom2 exitCode=137
NAME MEM USAGE / LIMIT MEM %
st 57.98MiB / 128MiB 45.29%
docker stats で、上限(LIMIT)に対して使用量がどこまで増えるかを見ます。上限に張り付いてから止まるなら、メモリの不足です。
| 直し方 | 内容 |
|---|---|
| 上限を上げる | --memory、compose の mem_limit(確認環境で 64MB の上限が設定された) |
| アプリの使う量を減らす | 一度に読み込むデータを分ける、など |
| アプリの上限をコンテナに合わせる | Java のヒープなど(下で説明) |
--memory-swap を --memory と同じ値にすると、スワップを使わない設定になります(Docker 公式ドキュメント)。確認環境ではこの設定で再現しました。
Java:ヒープの上限がコンテナより大きいと、137 になる
コンテナの上限 256MB で、Java のプログラム(メモリを使い続ける)を動かしました。
| Java の設定 | ヒープの上限(maxMemory) |
結果 |
|---|---|---|
| 指定なし | 121MB(コンテナの上限から自動で決まった) | java.lang.OutOfMemoryError: Java heap space(exit=1、OOMKilled=false) |
-Xmx512m(コンテナより大きい) |
512MB | 200MB まで使ったところで止まり、exit=137、OOMKilled=true |
-XX:MaxRAMPercentage=75 |
185MB | コンテナの上限の 75% |
-Xmx をコンテナの上限より大きくすると、Java のエラーにならず、ログも残らずに 137 で止まりました。 指定しなければ、Java がコンテナの上限からヒープを決め、Java の OutOfMemoryError(原因が分かるエラー)になりました。
コンテナの中の Java は、-Xmx を固定せず、-XX:MaxRAMPercentage でコンテナの上限に対する割合で指定するのが安全です。ヒープのほかにもメモリを使うので、100% にはしません。Java の OutOfMemoryError の種類は、関連記事の「Java OutOfMemoryErrorの原因と対処|メッセージ別に解説」で扱っています。Node.js のヒープの上限は、関連記事の「JavaScript heap out of memoryの直し方|Node.js」で扱っています。
原因2:docker stop で、10秒後に強制終了された(OOMKilled=false)
$ time docker stop app
real 0m10.1s
$ docker inspect app --format 'exit={{.State.ExitCode}} OOMKilled={{.State.OOMKilled}}'
exit=137 OOMKilled=false
docker stop は、まず終了の信号(SIGTERM)を送り、10秒たっても止まらなければ、強制終了(SIGKILL)します(Docker 公式ドキュメント)。メインのプロセスが SIGTERM で止まらないと、毎回 10 秒待たされて 137 になります。
| 起動のしかた | docker stop にかかった時間 |
終了コード |
|---|---|---|
sh -c 'sleep 300' |
10.1 秒 | 137 |
sleep 300(直接実行) |
10.2 秒 | 137 |
--init を付けて sleep 300 |
0.1 秒 | 143(128 + 15:SIGTERM) |
SIGTERM を受け取って終了する処理(trap)を書いた |
0.1 秒 | 0 |
コンテナの中で最初に動くプロセス(PID 1)は、SIGTERM を受け取る処理を書いていないと、信号を無視して動き続けました。 --init を付けると、信号を中継する小さなプロセスが PID 1 になり、すぐに止まりました。
| 直し方 | 書き方 |
|---|---|
--init を付ける |
docker run --init ...、compose なら init: true |
| アプリで SIGTERM を受け取って終了する | フレームワークの終了処理(graceful shutdown)を有効にする |
| 待ち時間を変える | docker stop -t 3(確認環境では 3 秒で強制終了) |
docker compose down や再起動のたびに 10 秒かかり、終了コードが 137 なら、この原因です。メモリの問題ではないので、メモリの上限を上げても直りません。
終了コードの早見表
| 終了コード | 意味 |
|---|---|
| 0 | 正常に終了 |
| 1 | アプリのエラー(Java の例外で終了した場合など) |
| 137 | SIGKILL(128 + 9):メモリの上限、docker stop の時間切れ、docker kill |
| 143 | SIGTERM(128 + 15):docker stop で正しく止まった |
確認の手順(チェックリスト)
| 順番 | 確認すること | 方法 |
|---|---|---|
| 1 | OOMKilled か | docker inspect ... {{.State.OOMKilled}} |
| 2 | true なら、使用量 | docker stats、docker events --filter event=oom |
| 3 | Java・Node.js か | ヒープの上限がコンテナの上限より大きくないか |
| 4 | false なら、止め方 | docker stop に 10 秒かかっていないか |
| 5 | 信号を受け取れるか | --init、アプリの終了処理 |
| 6 | 上限の設定 | --memory、compose の mem_limit |
よくある質問
Q. compose で init を設定するとどうなりますか。
A. 確認環境では、init: true を書いたサービスを docker compose stop すると、0.2 秒で止まり、終了コードは 143 でした。
Q. コンテナが消えてしまい、docker inspect できません。
A. --rm を付けて起動していると、止まったときにコンテナが消えます。原因を調べる間は --rm を外すか、docker events --filter event=oom を流しておくと、OOM が起きた瞬間に記録が残ります。
まとめ
- 137 は SIGKILL で止められたという意味。メモリ不足とは限らない
docker inspectのOOMKilledで見分ける(true ならメモリ)- Java の
-Xmxがコンテナより大きいと、ログも残らずに 137。MaxRAMPercentageで割合を指定 docker stopに 10 秒かかって 137 なら、SIGTERM を受け取れていない。--initを付ける- 正しく止まれば 143(SIGTERM)か 0
参考・出典
確認日はいずれも 2026年10月11日です。
- Docker Docs「docker container stop」:https://docs.docker.com/reference/cli/docker/container/stop/
- Docker Docs「Resource constraints」:https://docs.docker.com/engine/containers/resource_constraints/
- Docker Docs「docker container run」(--init):https://docs.docker.com/reference/cli/docker/container/run/
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Docker Exited (137)の原因と直し方|OOMKilled」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。