2026年11月12日

2026年11月12日

Docker CPU and Memory Limits: How to Set Container Resource Limits

This article is a localized edition of the Japanese original. Read the Japanese original

Introduction

This article covers problems such as: a WordPress container running in Docker uses unlimited memory and the server goes down from OOM, one container takes all the CPU and slows down the others, or you do not know how to set resource limits in docker-compose.yml.

Symptoms and causes

  • A container uses too much memory and its process is killed by the host's OOM killer
  • One container monopolizes all the CPUs and the other containers respond slowly
  • You checked resource usage with docker stats but no limits are set
  • docker-compose v3 and v2 use different syntax for resource limits, so the limits do not work

How to fix it

Step 1: Check current resource usage

# ✅ Show resource usage of all containers in real time
docker stats
# → CONTAINER  CPU %  MEM USAGE / LIMIT  MEM %
# → wordpress  45.2%  512MiB / unlimited  -

# ✅ Resource usage of specific containers
docker stats wordpress mysql --no-stream
# --no-stream: show the output only once

# ✅ Check the container resource limits
docker inspect wordpress --format='{{json .HostConfig.Memory}}'
# → 0 ← 0 means unlimited

# ✅ Show the container's detailed resource settings
docker inspect wordpress | grep -A 10 '"Memory"'

Step 2: Set resource limits with docker run

# ✅ Start a container with a memory limit
docker run -d \
    --name wordpress \
    --memory="512m" \
    --memory-swap="1g" \
    -p 80:80 \
    wordpress:latest

# ✅ Set a CPU limit
docker run -d \
    --name wordpress \
    --cpus="1.5" \
    --memory="512m" \
    -p 80:80 \
    wordpress:latest
# --cpus="1.5": the container can use 1.5 cores of CPU

# ✅ Specify a CPU set (pin to physical cores)
docker run -d \
    --name wordpress \
    --cpuset-cpus="0,1" \
    --memory="512m" \
    wordpress:latest
# --cpuset-cpus="0,1": only CPU0 and CPU1 can be used

# ✅ Set the relative CPU share (default 1024)
docker run -d \
    --cpu-shares=512 \
    --name low-priority-task \
    busybox sleep 3600
# 512 is half the CPU priority of other containers (1024)

Step 3: Set resource limits in docker-compose.yml

# ✅ docker-compose.yml (Compose v3.x / Docker Swarm)
version: "3.8"

services:
  wordpress:
    image: wordpress:latest
    ports:
      - "80:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_NAME: wordpress
    deploy:
      resources:
        limits:
          cpus: "1.0"
          memory: 512M
        reservations:
          cpus: "0.5"
          memory: 256M
    depends_on:
      - db

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_DATABASE: wordpress
    deploy:
      resources:
        limits:
          cpus: "0.5"
          memory: 256M
# ✅ Apply resource limits with docker-compose (non-Swarm)
# docker-compose up needs the --compatibility flag
docker-compose --compatibility up -d

# ✅ docker-compose v2 format (non-Swarm)
# docker-compose.yml
services:
  wordpress:
    mem_limit: 512m
    mem_reservation: 256m
    cpus: 1.0

Step 4: Change the limits of an existing container

# ✅ Change the memory limit of a running container
docker update --memory="1g" --memory-swap="2g" wordpress
# → wordpress ← success

# ✅ Change the CPU limit of a running container
docker update --cpus="2.0" wordpress

# ✅ Update multiple containers at once
docker update --memory="512m" wordpress mysql nginx

# ✅ Check that the change was applied
docker inspect wordpress --format='
Memory: {{.HostConfig.Memory}}
NanoCPUs: {{.HostConfig.NanoCpus}}'
# → Memory: 1073741824 (= 1GB in bytes)
# → NanoCPUs: 2000000000 (= 2.0 CPUs)

# ✅ Check whether the container was killed by the OOM killer
docker inspect wordpress --format='{{.State.OOMKilled}}'
# → false ← normal
# → true ← killed by OOM (the memory limit is too strict)

Step 5: Optimize resources for the WordPress container

# ✅ Practical resource settings for WordPress + MySQL
# docker-compose.yml

services:
  wordpress:
    image: wordpress:php8.2-fpm
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_NAME: wordpress
      WORDPRESS_DB_USER: wpuser
      WORDPRESS_DB_PASSWORD: wppassword
      # ✅ PHP-FPM memory settings
      PHP_MEMORY_LIMIT: 256M
      PHP_MAX_EXECUTION_TIME: 60
    mem_limit: 512m
    cpus: 1.0

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_DATABASE: wordpress
    volumes:
      - ./mysql.cnf:/etc/mysql/conf.d/custom.cnf
    mem_limit: 256m
    cpus: 0.5

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    mem_limit: 128m
    cpus: 0.25
# ✅ Continuously monitor container resource usage
watch -n 5 'docker stats --no-stream'

# ✅ Monitor containers with Prometheus + Grafana (for production)
docker run -d \
    --name cadvisor \
    --volume=/var/run/docker.sock:/var/run/docker.sock:ro \
    --publish=8080:8080 \
    gcr.io/cadvisor/cadvisor:latest

Notes

  • Set --memory-swap to a value equal to or larger than --memory (with --memory=512m --memory-swap=512m, swap is disabled. To set a limit that includes swap, make memory-swap larger than memory, as in --memory-swap=1g)
  • The deploy.resources settings in docker-compose, which are meant for Swarm, are normally ignored by docker-compose up. Outside Swarm, use mem_limit/cpus or use the --compatibility flag

Summary

To set Docker resource limits: (1) check real-time CPU and memory usage with docker stats and the current limits with docker inspect; (2) set limits when starting a container with docker run --memory="512m" --cpus="1.0"; (3) configure them in Compose with deploy.resources.limits in docker-compose.yml (Swarm) or mem_limit/cpus (non-Swarm); (4) change the limits of a running container with docker update --memory --cpus and confirm OOM kills with the OOMKilled flag; (5) allocate appropriate memory to WordPress, MySQL, and Nginx and monitor container resources with cAdvisor.

Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)

お気軽にご相談ください

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