How to limit CPU and memory usage of containers in Docker Compose?

Publish: 2023-05-15 | Modify: 2023-05-15

Recently, while using the open source analytics tool Umami, I found that the CPU and memory usage was frequently maxed out, causing other services to be unable to function properly. I deployed Umami using docker-compose, so I decided to limit the CPU and memory usage of the containers using docker-compose to solve this problem.

Umami

Complaints

So I went to search for relevant documentation to find methods for limiting container resource usage, and I felt that Docker's design of docker-compose was a bit confusing.

  1. First, there are different versions of docker-compose, 1.x and 2.x, with different features.
  2. The version in the docker-compose.yaml file also has multiple versions (1.x-3.x), each with different features.
  3. The official documentation does not clearly state the differences between the versions, and the upgrade speed is quite fast.

Limiting CPU and Memory with docker-compose

I will directly paste the complete docker-compose.yaml file for Umami:

---
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:[email protected]:3306/umami
      DATABASE_TYPE: mysql
      HASH_SALT: replace-me-with-a-random-string
    restart: always
    network_mode: "host"

The limiting instructions are in the deploy.resources.limits section. Note the position of the nodes. The limitations specified above mean:

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

When we start it, the command needs to be modified, otherwise it will not take effect:

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

The key here is to add the --compatibility parameter to run in compatibility mode, otherwise the limitations will not take effect.

Verification

After limiting the CPU and memory of the container using the above methods, continue to use the command docker stats to view the container's resource usage:

docker stats

You can see that the umami container has been successfully limited to 500MB of memory.

Conclusion

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

Comments