2026年8月18日
2026年8月18日
Dockerのリソース制限(CPU・メモリ)設定|docker run・Composeでの書き方とOOMの見分け方
Dockerのコンテナは、何も指定しなければホストのCPUとメモリを上限なく使えます。1つのコンテナが暴走すると同じサーバーの他のコンテナやSSHまで重くなるため、本番では --memory と --cpus で上限を決めておくのが基本です。この記事では、docker run とDocker Composeでの指定方法、動いているコンテナの上限を変える方法、メモリ不足で強制終了(OOM)されたかの見分け方、WordPress(PHP-FPM・MySQL)で上限を決めるときの考え方を説明します。
内容はLinux上のDocker Engineの安定版(2026年10月現在)とcgroup v2の環境を前提にしています。Docker DesktopではDocker自体が仮想マシンの中で動くため、その仮想マシンに割り当てたCPU・メモリが全コンテナの合計の上限になります。割り当ては設定画面のリソース関連の項目で変えられます(項目名はバージョンによって異なります)。
まず今の使用量を見る
上限を決める前に、普段どれだけ使っているかを確認します。
# 全コンテナの使用量を1回だけ表示
docker stats --no-stream
# 特定のコンテナを継続して表示(Ctrl+Cで終了)
docker stats web db
MEM USAGE / LIMIT の右側が上限です。上限を設定していなければ、ホストのメモリ全体が表示されます。CPU % は1コア分の使用を「100」として数えるため、4コアを使い切ると400前後の値になります。
ピーク時の値を知りたいので、アクセスが多い時間帯やバッチ処理の実行中にも見ておきます。継続的に記録したい場合は、cAdvisorなどの監視ツールを使うと推移をグラフで確認できます。
docker runでの指定
docker run -d --name web \
--memory 512m \
--memory-swap 512m \
--cpus 1.5 \
--pids-limit 200 \
nginx:stable
主なオプションの意味は次のとおりです。
--memory(-m):メモリの上限。512m、2gのように単位を付けます。超えそうになるとカーネルがコンテナ内のプロセスを強制終了します。--memory-swap:メモリとスワップを合わせた上限。--memoryと同じ値にするとスワップを使わない設定になります。指定しない場合は、メモリ上限と同じ量までスワップを使える設定になります。--memory-reservation:上限より小さい「目安」の値。ホストのメモリが足りなくなったときに、この値まで使用量を減らすよう働きかけます。上限の代わりにはなりません。--cpus:使えるCPUの量。1.5なら1.5コア分です。超えて使おうとすると止められるのではなく、待たされて遅くなります。--cpu-shares:CPUが取り合いになったときの配分の重み。空いているときは制限されません。--cpuset-cpus:使ってよいCPUコアの番号(例:0,1)。--pids-limit:コンテナ内のプロセス数の上限。fork爆弾のような暴走を防ぎます。
メモリとCPUの違いは押さえておく価値があります。CPUは上限に達しても「遅くなる」だけですが、メモリは上限に達すると「プロセスが殺される」ため、余裕を持たせた値にします。
なお、ホストのカーネル設定によっては、起動時に「スワップの制限に対応していない」という警告が出て --memory-swap が効かないことがあります。docker info の末尾に出る警告を確認してください。
動いているコンテナの上限を変える
docker update で、コンテナを作り直さずに上限を変えられます。
docker update --memory 1g --memory-swap 1g --cpus 2 web
docker inspect --format '{{.HostConfig.Memory}} {{.HostConfig.NanoCpus}}' web
inspect で表示される値は、メモリがバイト、CPUが10億分の1コア単位です(2 コアなら 2000000000)。メモリの上限を下げる場合、現在の使用量より小さい値にはできないことがあります。また docker update はその場限りの変更なので、Composeで管理しているコンテナは、次に作り直したときに compose.yaml の値に戻ります。恒久的な変更は設定ファイルに書きます。
Docker Composeでの指定
Composeでは deploy.resources に書く方法が公式ドキュメントで案内されています。現行のDocker Compose(v2系、docker compose コマンド)では、Swarmを使わない通常の起動でもこの上限が適用されます。
services:
wordpress:
image: wordpress:php8.3-fpm
deploy:
resources:
limits:
cpus: "1.0"
memory: 768M
pids: 300
reservations:
memory: 256M
db:
image: mysql:8.4
deploy:
resources:
limits:
cpus: "1.0"
memory: 1G
サービス直下に mem_limit や cpus を書く古い書き方も引き続き読み込まれますが、同じ項目を deploy と両方に書くと分かりにくくなるので、どちらかに統一します。設定したら docker compose up -d で作り直し、docker stats の LIMIT 列が変わったことを確認します。
古いdocker-compose(v1系)を使っている環境では deploy が無視されることがありました。上限が効いていないように見えるときは、まず docker compose version で使っているツールを確かめてください。
メモリ不足で落ちたかを見分ける
コンテナが突然再起動したり止まったりしたときは、メモリ上限に達して強制終了されたかを確認します。
docker inspect --format 'OOMKilled={{.State.OOMKilled}} ExitCode={{.State.ExitCode}}' web
OOMKilled=true なら、コンテナのメモリ上限で強制終了されています。終了コード 137 はSIGKILLで終了したことを示し、OOMでよく見られますが、docker kill など他の理由でも同じ値になります。OOMKilled が false でもメインプロセス以外(PHP-FPMの子プロセスなど)が殺された場合は、コンテナ自体は動き続けるため、この方法では分かりません。その場合はホストで sudo dmesg -T | grep -i -E "killed process|oom" を実行し、カーネルのログを確認します。
OOMが出たときの対処は、原因によって次の順で考えます。
- 一時的なピーク(大量アクセス、画像の一括処理)なら、上限を少し上げるか、同時に動くプロセス数を減らします。
- 時間とともに使用量が増え続けるなら、アプリのメモリリークを疑います。上限を上げても時間稼ぎにしかなりません。
- アプリ自身のメモリ設定(PHPの
memory_limit、Node.jsのヒープ上限、MySQLのバッファ)がコンテナの上限より大きいなら、アプリ側の設定をコンテナに合わせます。
WordPressで上限を決める考え方
WordPressのコンテナでは、PHPの memory_limit とコンテナの --memory は別物です。memory_limit はPHPの1リクエストあたりの上限で、コンテナの上限は全プロセスの合計です。PHP-FPMを使う場合、おおよそ「1プロセスの使用量 × pm.max_children」がコンテナ内で同時に必要になるメモリです。たとえば1プロセスが平均80MBで pm.max_children = 10 なら、PHPだけで800MB前後が必要になり、上限を512MBにすると混雑時にOOMが起きます。上限を決めたら、それに収まるよう pm.max_children を調整します。
MySQLやMariaDBのコンテナでは、innodb_buffer_pool_size を中心とするメモリ設定がコンテナの上限より大きいと、負荷がかかったときに落ちます。データベースは途中で強制終了されるとクラッシュリカバリーが走り、場合によってはデータの破損につながるため、上限には十分な余裕を持たせ、設定を変える前にはバックアップを取ってください。
上限の値は、ステージング環境で負荷テストやバックアップ処理を実行し、docker stats で実際のピークを確認してから決めるのが安全です。いきなり本番で厳しい値にすると、管理画面での画像アップロードやプラグインの更新など、たまにしか行わない重い処理で初めて問題が表に出ます。
まとめ
- 上限を決める前に
docker statsで平常時とピーク時の使用量を確かめます。 - メモリは
--memory(スワップを使わせないなら--memory-swapも同じ値)、CPUは--cpus、プロセス数は--pids-limitで制限します。CPUの上限は遅くなるだけ、メモリの上限は強制終了につながります。 - 動いているコンテナは
docker updateで変えられますが、Composeではdeploy.resourcesに書いて作り直すのが恒久的な方法です。 - 突然の停止は
docker inspectのOOMKilledとホストのdmesgで原因を確かめます。 - WordPressでは PHP-FPMのプロセス数とMySQLのバッファを、コンテナの上限に収まるように合わせます。