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期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?