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が出たときの対処は、原因によって次の順で考えます。

  1. 一時的なピーク(大量アクセス、画像の一括処理)なら、上限を少し上げるか、同時に動くプロセス数を減らします。
  2. 時間とともに使用量が増え続けるなら、アプリのメモリリークを疑います。上限を上げても時間稼ぎにしかなりません。
  3. アプリ自身のメモリ設定(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のバッファを、コンテナの上限に収まるように合わせます。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲