Skip to content
VDS · Docker і контейнери

Ліміти пам'яті та CPU для контейнерів

Як задати стелю пам'яті та CPU для контейнера, чому без неї один сервіс валить усі інші та як зрозуміти, що процес убив ядро.

Оновлено 23 серпня 2026 р.

За замовчуванням контейнер може зайняти всю пам'ять і всі ядра на машині. На VDS-1 з двома гігабайтами це закінчується передбачувано: один сервіс роздувається, ядро починає вбивати процеси, і падає не він, а база даних поруч.

Як задати стелю

services:
  app:
    image: ghcr.io/example/app:1.5.0
    deploy:
      resources:
        limits:
          memory: 768M
          cpus: "1.0"
        reservations:
          memory: 256M

Compose застосовує deploy.resources.limits навіть при звичайному docker compose up -d. Еквівалент для docker run:

docker run -d --memory 768m --cpus 1.0 --memory-swap 768m <image>

Якщо задати --memory-swap рівним --memory, це забороняє своп: чесне падіння краще за машину, яка ледь ворушиться годинами.

Скільки виділяти

Відштовхуйтеся від свого тарифу й залиште системі запас.

ТарифПам'ятьРозумна сумарна стеля для контейнерів
VDS-12 GBдо 1.5 GB
VDS-24 GBдо 3 GB
VDS-38 GBдо 6.5 GB
VDS-416 GBдо 14 GB
VDS-524 GBдо 21 GB
VDS-632 GBдо 29 GB

Залишок потрібен системі, файловому кешу й самому Docker. Сума лімітів, більша за обсяг пам'яті, — це не помилка конфігурації, а катастрофа, що насувається.

Щодо CPU: cpus: "1.0" — це одне повне ядро. На VDS-1 лише одне ядро, тож обмежувати там CPU майже немає сенсу, але на VDS-4 і вище варто не давати конфігурації сервера забирати всі шість.

Що насправді споживається

docker stats --no-stream
docker stats --no-stream --format "table {{.Name}}\t{{.MemUsage}}\t{{.CPUPerc}}"
free -h

Понаблюдайте за сервісом добу під навантаженням і ставте ліміт приблизно в півтора раза більше за пік. Занадто тісний ліміт гірший за його відсутність: сервіс перезапуститься саме тоді, коли він вам найпотрібніший.

Повноекранні htop і btop працюють лише в консолі «Screen» (VNC). Текстова консоль не передає розмір вікна, там завжди 80×24, і інтерфейс розсипається. Для швидких вимірювань у текстовій консолі використовуйте docker stats --no-stream і free -h.

Як зрозуміти, що процес убила пам'ять

docker inspect -f '{{.State.ExitCode}} {{.State.OOMKilled}}' <container>
sudo dmesg -T | grep -i -E "out of memory|killed process"

Код виходу 137 разом із OOMKilled: true — це однозначний вердикт. Далі у вас два варіанти: підняти ліміт, якщо він був занизький, або розібратися, чому застосунок постійно зростає — витік не лікують додаванням пам'яті, його лише відкладають.

Java та інші особливі випадки

Віртуальна машина Java досі іноді бачить пам'ять хоста, а не ліміт контейнера, і визначає розмір купи із запасом, якого немає. Задайте його явно:

environment:
  JAVA_TOOL_OPTIONS: "-Xmx512m -Xms256m"

Те саме стосується PostgreSQL (shared_buffers) і будь-якого сервісу з власним пулом.

Поширені помилки

  • Ліміти взагалі не задані. Найчастіша причина «машина зависла, нічого не відповідає».
  • Ліміт є, але немає перевірки стану. Контейнер убили, і він не перезапустився. Додайте restart: unless-stopped і healthcheck — дивіться оновлення контейнерів.
  • Ви забули про диск. Пам'ять ви обмежили, але записи впираються в стелю: дивіться швидкість диска.