Планувальник Docker RAM
Плануйте використання пам'яті контейнерів відносно доступного RAM.
Додати контейнер
Services
Custom
Загальний RAM використано
0 MB
Залишок
3584 MB
Зарезервовано для системи
512 MB
Fits comfortably
Good headroom for scaling and memory spikes.
Що таке калькулятор RAM для Docker?
Калькулятор RAM для Docker оцінює загальну пам'ять, необхідну для запуску набору Docker-контейнерів на сервері або домашньому сервері. Кожен контейнерний сервіс (база даних, вебсервер, моніторинг, медіасервер) має конкретні вимоги до пам'яті. Цей інструмент допомагає планувати апаратні потреби, підсумовуючи виділення пам'яті контейнерам з накладними витратами на хостову операційну систему та Docker-двигун.
Брак RAM є найпоширенішою причиною збоїв Docker-контейнерів та нестабільності сервера. На відміну від CPU, яким можна ділитися в часі, RAM є жорстким обмеженням — коли контейнер перевищує своє виділення пам'яті, Docker вбиває його (OOM — Out of Memory). Правильне планування запобігає несподіваним простоям і допомагає вам вирішити, чи оновлювати сервер або оптимізувати стек.
Як користуватися цим інструментом
Додайте контейнери, які ви плануєте запускати, та вкажіть їх вимоги до пам'яті. Інструмент підсумовує загальне, додає накладні витрати для ОС та Docker-двигуна та показує рекомендований загальний RAM. Він попереджає, якщо ваша запланована конфігурація перевищує типові апаратні конфігурації.
Обмеження пам'яті та резервування пам'яті
Docker надає два окремі важелі для керування обсягом RAM, який може використовувати контейнер: обмеження пам'яті та резервування пам'яті. Їх часто плутають, але вони слугують зовсім різним цілям.
Обмеження пам'яті (задається через --memory або mem_limit у файлі Compose) — це жорстка стеля. Docker застосовує його через підсистему груп управління Linux (cgroups). Контейнер ніколи не зможе виділити більше цього обсягу — якщо він спробує, втрутиться OOM Killer ядра Linux.
- --memory / mem_limit: жорстка верхня межа. Контейнер не може її перевищити. Використовується для захисту хоста від процесів, що вийшли з-під контролю.
- --memory-reservation / mem_reservation: м'яка підказка для планувальника. Планувальник Docker Swarm використовує це значення при прийнятті рішення про розміщення сервісів. Воно НЕ обмежує використання пам'яті контейнером — це лише мінімальна гарантія, яку Docker намагається дотримуватися.
- Поширена найкраща практика: встановлюйте резервування рівним очікуваному споживанню в стані спокою, а обмеження — максимуму, який ви готові дозволити. Наприклад, для контейнера, який у стані спокою споживає 200 МБ, але може піднятися до 600 МБ, варто встановити reservation=200m та limit=600m.
Якщо обидва прапорці не вказані, контейнер не матиме обмежень і може споживати всю доступну RAM хоста. На сервері, призначеному для одного завдання, це може бути прийнятним, але на домашній лабораторії з багатьма сервісами це суттєвий ризик.
Що відбувається, коли контейнер досягає обмеження пам'яті
Коли споживання пам'яті контейнером досягає значення, встановленого через --memory, OOM (Out of Memory) Killer ядра Linux примусово завершує найбільш прожерливий процес усередині контейнера. Docker фіксує це як код виходу 137 — стандартне завершення за сигналом POSIX 9 (SIGKILL). Ви побачите це у виводі docker ps --all або в журналах контейнера як «Exited (137)».
Код виходу 137 не означає, що ваш застосунок впав через помилку — це означає, що ядро примусово його зупинило, оскільки контейнер досяг налаштованої вами стелі RAM. Якщо ви бачите повторювані виходи з кодом 137 у стабільному застосунку, ваше обмеження пам'яті надто мале або навантаження зросло понад початкову оцінку. Збільшіть обмеження і знову відстежуйте ситуацію за допомогою docker stats.
Особливості управління пам'яттю в різних середовищах виконання
Різні середовища виконання мов програмування та рушії баз даних управляють пам'яттю по-різному. Встановлення обмеження пам'яті контейнера без урахування поведінки середовища виконання — одна з найпоширеніших причин несподіваних OOM-завершень.
- JVM (Java, Kotlin, Scala): JVM виділяє купу наперед. Без явних прапорців вона може зайняти значну частку доступної системної RAM при запуску. Завжди встановлюйте -Xmx (максимальний розмір купи) нижче за обмеження пам'яті Docker — загальна рекомендація: залишати щонайменше 25% запасу поверх -Xmx для позакупової пам'яті, накладних витрат на збирання сміття та нативних бібліотек.
- Node.js: V8 має стандартне обмеження купи (близько 1,5 ГБ на 64-розрядних системах у старих версіях). Якщо ваше обмеження Docker нижче, процес може бути завершений OOM Killer ще до того, як V8 ініціює збирання сміття. Використовуйте --max-old-space-size (у МБ) для обмеження купи старого покоління V8 і встановлюйте значення нижче обмеження пам'яті Docker.
- Бази даних (PostgreSQL, MariaDB, MySQL): бази даних за своєю природою активно використовують пам'ять — вони кешують гарячі сторінки у своєму спільному буферному пулі. Стандартне значення shared_buffers у PostgreSQL становить 128 МБ, але зазвичай налаштовується на 25% доступної RAM для виділених серверів. Усередині контейнера налаштуйте shared_buffers відповідно до вашого обмеження пам'яті, інакше база даних несподівано буде завершена під навантаженням.
- Медіасервери (Jellyfin, Plex): перекодування дуже інтенсивно використовує пам'ять. Одне перекодування у 4K може потребувати 1–3 ГБ понад споживання в стані спокою. Якщо ви вмикаєте апаратне прискорення перекодування, картина зі споживанням пам'яті суттєво змінюється. Перевіряйте фактичне використання сервером під реальним навантаженням перед встановленням кінцевих обмежень.
Поширені вимоги до пам'яті контейнерів
Наведені нижче цифри є лише приблизними орієнтирами для планування — фактичне споживання суттєво варіюється залежно від конфігурації, розміру набору даних, кількості користувачів та увімкнених функцій. Завжди вимірюйте за допомогою docker stats після запуску вашого реального робочого навантаження.
- PostgreSQL: 256 МБ–1 ГБ+ залежно від розміру бази даних та складності запитів.
- Nginx/Caddy: 50–128 МБ для типового використання як зворотного проксі.
- Grafana + Prometheus: 256 МБ + 512 МБ–2 ГБ для стеків моніторингу.
- Home Assistant: 256–512 МБ для домашньої автоматизації.
- Plex/Jellyfin: 1–4 ГБ залежно від транскодування та розміру бібліотеки.
- Легкі зворотні проксі (Traefik, Caddy, Nginx): зазвичай 30–150 МБ у стані спокою; це одні з найменш вимогливих до пам'яті сервісів, які можна запустити.
- Стеки моніторингу (Prometheus + Grafana): Prometheus масштабується залежно від кількості часових рядів, які він збирає та зберігає, — від кількох сотень МБ до кількох ГБ у великих середовищах. Grafana відносно легка — близько 100–300 МБ.
Приклад розрахунку розміру: типова домашня лабораторія на Raspberry Pi 4 (8 ГБ)
Щоб побачити, як накопичується розподіл RAM, розглянемо Raspberry Pi 4 з 8 ГБ, що запускає невеликий стек самохостингу:
- ОС хоста (Raspberry Pi OS Lite): ~300–500 МБ зарезервовано для ядра, системних процесів та самого рушія Docker
- Pi-hole (DNS-блокувальник реклами): обмеження 128 МБ — легкий сервіс із низькими накладними витратами
- Vaultwarden (менеджер паролів, сумісний з Bitwarden): обмеження 128 МБ — дуже легкий бінарний файл на Rust
- Home Assistant: обмеження 512 МБ — на основі Python, зростає з автоматизаціями та інтеграціями
- Jellyfin (медіасервер, програмне перекодування вимкнено): обмеження 1024 МБ — масштабується з розміром бібліотеки
- Portainer (інтерфейс управління контейнерами): обмеження 256 МБ
Сума цих обмежень: 500 (хост) + 128 + 128 + 512 + 1024 + 256 = приблизно 2,5 ГБ виділено. На пристрої з 8 ГБ залишається близько 5,5 ГБ запасу — комфортний буфер для кешування, пікових навантажень та майбутніх контейнерів. На Raspberry Pi 4 з 2 ГБ цей самий стек буде надлишково розподілений ще до врахування пікових навантажень. Калькулятор вище виконує саме такий вид арифметики для будь-якої комбінації обраних вами сервісів.
Чому надлишковий розподіл RAM є ризикованим
Надлишковий розподіл означає планування стека, чиї сумарні обмеження пам'яті перевищують фізичну RAM, доступну ОС хоста. Docker сам по собі цього не запобігає — він цілком готовий прийняти файл Compose, що розподіляє 10 ГБ між контейнерами на машині з 4 ГБ. Ризик проявляється під час виконання: коли фактичне використання всіма контейнерами наближається до фізичної RAM, ядро починає активно використовувати підкачку. Підкачка на SD-картках та USB-накопичувачах (поширені носії для домашніх лабораторій) на порядки повільніша за RAM і може спричиняти зависання всієї системи.
Сама ОС хоста також потребує простору понад те, що використовують контейнери. Кеш сторінок Linux, буфери ядра та системні служби конкурують за RAM. Як практичне правило: ніколи не плануйте стек, який залишає менше 10–15% загальної RAM вільними для хоста після підсумовування обмежень контейнерів. На пристрої з 4 ГБ це означає: тримайте щонайменше 400–600 МБ нерозподіленими.
Поради щодо оптимізації пам'яті
Встановіть обмеження пам'яті на всіх контейнерах (docker run --memory=512m), щоб запобігти поглинанню всієї доступної RAM одним контейнером. Використовуйте образи на основі Alpine, які менші та використовують менше пам'яті. Моніторте фактичне використання за допомогою 'docker stats' перед прийняттям остаточних рішень про розмір. Залишайте щонайменше 1–2 ГБ вільними для ОС хоста, кешування файлів та накладних витрат Docker. Swap-простір може бути захисною сіткою, але не повинен використовуватися в нормальній роботі.
Типові помилки при розрахунку RAM для Docker
- Відсутність будь-яких обмежень: без прапорців --memory будь-який контейнер може споживати всю RAM хоста, вивівши з ладу всі інші сервіси на машині.
- Плутанина між резервуванням та обмеженням: встановлення великого значення mem_reservation не обмежує використання — контейнер із великим резервуванням і без обмеження все одно може вичерпати RAM хоста.
- Ігнорування накладних витрат ОС хоста: розподілення 100% фізичної RAM між контейнерами не залишає нічого для ядра, рушія Docker та фонових процесів.
- Розрахунок за документацією образу, а не за фактичним використанням: офіційні образи часто вказують мінімальні вимоги. Фактичний RSS при реальному навантаженні може бути у 2–5 разів вищим. Завжди перевіряйте за допомогою docker stats.
- Забуття про налаштування купи середовища виконання: контейнери для застосунків JVM або Node без встановленого обмеження купи намагатимуться використати стільки пам'яті, скільки дозволяє обмеження контейнера — або перевищать його і спровокують OOM-завершення.
Часті запитання
Скільки RAM потребує сам Docker?
Сам Docker-двигун використовує близько 100–200 МБ RAM. Хостова Linux-ОС зазвичай потребує 500 МБ–1 ГБ для мінімальної серверної установки. Разом плануйте близько 1–1,5 ГБ накладних витрат до виділення контейнерів. На сервері з 16 ГБ у вас реально є близько 14–15 ГБ для контейнерів.
Що відбувається, коли контейнер вичерпує пам'ять?
Коли контейнер перевищує своє обмеження пам'яті, OOM-кілер ядра Linux завершує його. Docker повідомляє про це як код виходу 137. Без обмежень пам'яті несправний контейнер може споживати всю доступну системну RAM, потенційно аварійно завершуючи інші контейнери та хостову ОС. Завжди встановлюйте явні обмеження пам'яті та моніторте використання.
Чи слід налаштовувати підкачку для контейнерів Docker?
Docker дозволяє окремо встановити обмеження підкачки за допомогою --memory-swap. Якщо ви встановите --memory=512m та --memory-swap=1g, контейнер отримає 512 МБ RAM плюс 512 МБ підкачки. Підкачка забезпечує страховку, яка запобігає негайним OOM-завершенням, але покладання на неї у звичайній роботі суттєво знижує продуктивність — особливо на флеш-носіях. Використовуйте підкачку як крайній резерв, а не замінник достатнього обсягу RAM. На системах без явного прапорця --memory-swap Docker стандартно встановлює підкачку в подвійному розмірі від обмеження пам'яті.
Як дізнатися, скільки RAM фактично використовують мої запущені контейнери?
Запустіть docker stats, щоб побачити в реальному часі споживання CPU, пам'яті та обмеження пам'яті для кожного запущеного контейнера. Стовпець MEM USAGE показує поточний RSS (розмір резидентного набору) контейнера. Порівняйте це з налаштованими обмеженнями, щоб побачити, скільки запасу є у кожного контейнера. Для одноразового знімка використайте docker stats --no-stream. Також можна перевірити конкретний контейнер за допомогою docker inspect <name> і знайти поле MemoryStats.