How to Limit CPU and Memory Usage for Containers in Docker Compose

docker compose cpu memory limitsdocker compose resource constraintsumami docker deploymentdocker compose compatibility modecontainer resource management
Published·Modified·

Recently, while using the open-source analytics tool Umami, I noticed that CPU and memory usage frequently reached 100%, causing other services to malfunction. Since I deployed Umami using docker-compose, I decided to use docker-compose to limit the container's CPU and memory usage to resolve this issue.

Umami Resource Usage

Frustrations

I searched the documentation for methods to limit container resource usage, and my impression is that Docker's design for docker-compose is somewhat chaotic.

  1. The docker-compose tool has different versions (1.x and 2.x) with distinct features.
  2. The version field inside docker-compose.yaml also has multiple versions (1.x to 3.x), each with different features.
  3. The official documentation does not clearly specify the differences between versions, and the version upgrade speed is very fast.

Limiting CPU and Memory in Docker Compose

Here is the complete content of the Umami docker-compose.yaml file:

---
version: '3'
services:
  umami:
    image: docker.umami.dev/umami-software/umami:mysql-latest
    deploy:
      resources:
        limits:
          cpus: '0.50'
          memory: 500M
        reservations:
          cpus: '0.25'
          memory: 200M
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: mysql://umami:xxx@127.0.0.1:3306/umami
      DATABASE_TYPE: mysql
      HASH_SALT: replace-me-with-a-random-string
    restart: always
    network_mode: "host"

The restriction command is located in the deploy.resources.limits section. Note the node position; the meaning of this section is:

The Umami service's CPU usage is limited to a maximum of 50% of CPU capacity, and memory usage is limited to a maximum of 500MB. At the same time, this service requires at least 25% of CPU and 200MB of memory.

When starting the service, the command needs to be modified, otherwise, the restrictions will not take effect:

# Original startup command
docker-compose up -d
# Need to add the --compatibility parameter to run in compatibility mode
docker-compose --compatibility up -d

The key here is adding the --compatibility parameter to run in compatibility mode; otherwise, the limits will not work.

Verification

After limiting the container's CPU and memory using the method above, you can use the docker stats command to check the container's resource usage:

Docker Stats Output

As shown, the umami container has been successfully limited to 500MB of memory.

Summary

  1. The version design of docker-compose is very chaotic, and I could not find clear official documentation comparing features.
  2. To limit memory in docker-compose.yaml, you need to add the deploy.resources.limits node.
  3. When starting docker-compose, you must add the --compatibility parameter to run in compatibility mode; otherwise, the limits will not take effect.