Setting Maximal Memory in Docker and Docker Compose

As usual, Docker is causing tons on problems in production because of missing documentation. So today’s problem is how to limit memory usage for process in Docker container if you use Docker Compose.

Setting memory limit for whole container requires cgroups support and can be used only with Docker Compose services mode. Usually we run just only single process in each container, so limiting memory on single process should be equivalent to limiting whole containers usage.

If you want to run docker-compose up you have only ulimits available to you. Other options like ‘mem_limit’ or ‘deploy’ options are not supported in that mode.

Fortunately, Docker does not limit option names you can put in ulimits section in docker-compose.yaml file (see here basically any option will be translated into corresponding setrlimit call)

This allows usage of RLIMIT_AS option.

Putting following in your docker-compose.yaml file will effectively limit memory usage of each process in container.

  ulimits:
    as:
      soft: 1300000000
      hard: 1300000000

Size is specified in bytes. Other settigns (RSS, DATA, STACK) do not let you effectively limit process memory usage.

Bad part is that this is not visible through normal Linux kernel procfs and you cannot check it in run-time.

What causes most pain for me, that this is NOT DOCUMENTED anywhere in Docker documentation at all.

Additional info on checking resource usage on processes/groups.

/proc/NNN/status shows single process’es status and memory usage
/proc/NNN/limits shows single process limits (but does not show Address space 🙁 )

to get PID from docker you can run:
docker ps and note container ID, then run docker top ID8a718a717 and note process ID from there.

You can look up current cgroup settings under /sys/fs/cgroup/*/docker/containerID/

Memory settings, for example, are located under /sys/fs/cgroup/memory/docker/containerID/memory.stat .