Сервер с 4 ГБ ОЗУ: сравниваем варианты настройки
На сервере с 4 ГБ памяти можно разместить сайт, приложение и базу данных, но не без компромиссов. Сравниваем четыре схемы размещения, распределяем память и определяем, когда пора выносить компоненты.

4 ГБ оперативной памяти достаточно для небольшого веб-приложения, но недостаточно, чтобы бездумно запустить на одном хосте несколько тяжёлых сервисов. На Ubuntu 24.04 LTS с Nginx, приложением и PostgreSQL узким местом обычно становится не процессор, а память: база начинает вытеснять кеш, приложение получает OOM, а сайт отвечает 502. Ниже — четыре рабочих варианта размещения и критерии выбора без обещаний, что одна схема подойдёт всем.
Исходные условия: что именно нужно уместить в 4 ГБ
Для сравнения возьмём один виртуальный сервер с 4 ГБ RAM, двумя виртуальными CPU, SSD и Ubuntu Server 24.04 LTS. На нём работает один веб-проект: Nginx принимает HTTP-запросы, приложение обрабатывает бизнес-логику, PostgreSQL хранит данные. Файлы пользователя и резервные копии не считаем частью оперативной памяти, но их дисковая активность влияет на производительность.
Главная ошибка — считать все 4096 МБ доступными приложению. Часть памяти сразу займут ядро Linux, systemd, SSH, сетевые службы, файловый кеш и сам Nginx. Фактический запас зависит от диска, драйверов, журналирования и числа фоновых процессов. Поэтому планировать нужно не «4 ГБ на приложение», а бюджет для каждого компонента и резерв на всплеск.
Сноска. OOM Killer — механизм ядра Linux, который завершает один или несколько процессов, когда системе не хватает памяти и освободить её больше неоткуда. Чаще всего под удар попадает самый крупный или наиболее подходящий по внутренним критериям процесс, поэтому предсказать результат только по названию службы нельзя.
Четыре схемы размещения
Вариант 1. Всё на одном хосте без контейнеров
Nginx, приложение и PostgreSQL запускаются как обычные службы systemd. Это самый экономный по памяти вариант: нет отдельного контейнерного окружения и лишних процессов-обвязок. Он хорошо подходит для одного небольшого проекта, тестового стенда или внутреннего сервиса.
Цена экономии — связность. Обновление библиотеки приложения, миграция базы и перезапуск сервисов происходят на одном узле. Если PostgreSQL съест память во время тяжёлого запроса, он может вытеснить приложение. Если приложение начнёт создавать слишком много рабочих процессов, пострадает база.
Вариант 2. Docker Compose на том же сервере
Сервисы запускаются в контейнерах, а их конфигурация описывается декларативно. Это удобнее для повторяемого развёртывания: версии приложения и базы фиксируются, запуск можно воспроизвести на другом хосте. Но Docker не создаёт дополнительную память. Контейнеры используют тот же общий ресурс, а overlay-файловая система и фоновые процессы добавляют накладные расходы.
Compose имеет смысл, если вам важны воспроизводимость и единый процесс доставки. Для одного сайта, который обновляется вручную раз в несколько месяцев, контейнеризация может добавить сложности без заметного выигрыша.
Вариант 3. Приложение на сервере, база данных отдельно
На маленьком сервере остаются Nginx и приложение, а PostgreSQL переезжает на управляемый сервис или отдельную виртуальную машину. Это самый заметный способ освободить память и отделить жизненный цикл базы от веб-узла.
Цена — деньги и сеть. Появляется задержка между приложением и базой, нужно настроить защищённое соединение, правила доступа, резервное копирование и контроль расходов. Такой вариант особенно полезен, если база уже заметно потребляет память или приложение нельзя остановить из-за обслуживания PostgreSQL.
Вариант 4. Один сервер, но с жёсткими лимитами
Все компоненты остаются на одном хосте, однако для служб задаются ограничения по памяти и числу процессов. Это можно сделать через параметры systemd или ограничения контейнерного рантайма. Лимиты не ускоряют систему, зато уменьшают вероятность, что один сервис бесконтрольно вытеснит остальные.
У этого подхода есть неприятная сторона: ограниченный процесс начнёт падать раньше. Это лучше неконтролируемого OOM, только если у вас есть мониторинг, понятные журналы и запасной сценарий. Лимит без наблюдения превращается в скрытую причину случайных 500 и 502.
| Схема | Память | Сложность эксплуатации | Когда выбирать | Главная цена |
|---|---|---|---|---|
| Службы на хосте | Минимальные накладные расходы | Низкая или средняя | Один небольшой проект | Сильная связанность компонентов |
| Docker Compose | Небольшие накладные расходы | Средняя | Нужно воспроизводимое развёртывание | Больше слоёв и точек отказа |
| База отдельно | Максимально разгружает веб-хост | Средняя или высокая | База растёт или критична к сбоям | Стоимость и сетевые задержки |
| Лимиты ресурсов | Не меняет общий объём | Средняя | Нужно изолировать сервисы | Ограниченный процесс может завершаться с ошибкой |
На сервере с 4 ГБ памяти выигрывает не самый «лёгкий» стек, а схема, в которой понятно, кто получит память первым и что произойдёт при её нехватке.
Как распределять память без гадания
Начните с измерений на реальном трафике. Смотрите не только среднее потребление, но и пики во время деплоя, резервного копирования, фоновых задач и тяжёлых запросов. Команды вроде free -h, top или vmstat показывают состояние в моменте, а для решения о миграции нужна история. Подойдут метрики вашего мониторинга, журналы ядра и статистика самого приложения.
- Зафиксируйте базовую линию. Измерьте память после загрузки и через несколько часов обычной работы. Отдельно запишите RSS процессов приложения, PostgreSQL, Nginx и фоновых задач. Если сборщика метрик нет, начните хотя бы с регулярных снимков, но не делайте вывод по одному замеру.
- Оставьте резерв. Не отдавайте приложению весь доступный объём. Резерв нужен для обновлений, временных буферов, новых соединений и файлового кеша. Точную величину нельзя универсально назвать: она зависит от пиков и профиля запросов, поэтому её определяют по графику, а не по шаблонной рекомендации.
- Настройте PostgreSQL под фактический размер нагрузки. В PostgreSQL 16 параметры памяти для операций сортировки, соединений и кеша влияют по-разному. Особенно опасны настройки, которые умножаются на число одновременных подключений: один небольшой лимит на соединение может превратиться в большой общий расход.
- Ограничьте параллелизм приложения. Число рабочих процессов или потоков должно помещаться в бюджет памяти. Увеличение количества workers не всегда повышает скорость: каждый процесс может иметь собственное рабочее состояние и копию части данных.
- Проверьте сценарий нехватки. Создайте безопасную нагрузку на тестовом стенде или в согласованное окно, а затем проверьте журналы ядра и служб. Результат считается приемлемым, если при пике сервис деградирует предсказуемо, а не произвольно теряет базу, приложение и SSH.
Swap: страховка, а не дополнительные 4 ГБ
Swap позволяет временно переместить часть страниц памяти на диск. Он может дать системе время пережить короткий пик, но не превращает сервер с 4 ГБ RAM в сервер с 8 ГБ. Если рабочий набор постоянно не помещается в оперативной памяти, начинается активный обмен с диском, растут задержки и очередь IO.
Swap полезен как аварийный буфер для редких всплесков и фоновых задач. Он не решает проблему постоянного дефицита памяти, медленного диска или слишком большого числа процессов. После настройки отслеживайте не только наличие swap, но и интенсивность его использования, задержки диска и события OOM.
Что ломается первым
База данных получает слишком много соединений
Каждое соединение расходует память, а параллельные сортировки и хеш-операции могут временно увеличить потребление. Если приложение открывает отдельное соединение для каждого запроса или процесса, лимит базы быстро становится частью проблемы. Используйте пул соединений и проверьте, совпадает ли его размер с числом workers приложения.
Фоновые задачи конкурируют с веб-запросами
Импорт, генерация отчёта, обработка изображений и резервное копирование часто запускаются в самый неподходящий момент. Разнесите такие задачи по времени, ограничьте их параллелизм и следите за размером временных файлов. Если обработка регулярная и тяжёлая, это аргумент в пользу отдельного worker-узла.
Контейнер имеет лимит, но хост — нет
Изолировать только приложение недостаточно. PostgreSQL, Docker, журналирование и фоновые процессы тоже участвуют в расходе памяти. Проверяйте ограничения на уровне каждого сервиса и общую картину на хосте. Лимит контейнера не защищает от исчерпания памяти системой в целом.
Включённый кеш скрывает реальный дефицит
Linux использует свободную память для файлового кеша, и это нормально. Смотрите на доступную память, активность swap, давление на память и ошибки OOM, а не только на строку «used». Снижение кеша само по себе не означает неисправность.
Когда выбирать каждый вариант
Для небольшого сайта или приложения без тяжёлых фоновых задач начните со служб на хосте. Если команда уже использует контейнеры и умеет видеть лимиты, выбирайте Docker Compose, но не рассчитывайте на экономию памяти. Если PostgreSQL занимает большую часть пикового бюджета, переносите его отдельно, а не пытайтесь бесконечно уменьшать кеш. Если проблема — непредсказуемое поведение компонентов, добавляйте лимиты и алерты, но сначала убедитесь, что после ограничения у системы останется рабочий запас.
Не пытайтесь решить архитектурную проблему увеличением swap или отключением всех кешей. Такие меры могут отсрочить сбой, но не устраняют конкуренцию за RAM.
Что делать дальше
Соберите неделю измерений: доступная память, swap, OOM-события, RSS ключевых процессов, число подключений к PostgreSQL, задержки запросов и доля ответов 5xx. Затем сравните пиковые значения с бюджетом каждого компонента. Если запас исчезает только во время редких задач, ограничьте их расписание и параллелизм. Если память заканчивается в обычный час пик, не оптимизируйте вслепую: сначала решите, что выносить — базу, фоновые задачи или само приложение.
После изменения схемы повторите те же замеры. Сравнивать нужно одинаковые условия: тот же объём данных, тот же сценарий нагрузки и тот же период наблюдения. Только так будет понятно, помогла ли новая архитектура, а не просто изменился трафик.
Тест и проверочная: Быстрые ответы с объяснением, почему остальные варианты неверны
Спросить за 10 ₽Источники: PostgreSQL 16: Resource Consumption, systemd: Resource Control
Частые вопросы
Хватит ли 4 ГБ RAM для сайта и PostgreSQL на одном сервере?
Нужно ли сразу создавать большой swap?
Docker экономит память по сравнению с обычной установкой?
Что вынести первым, если сервер начал упираться в память?
Что делать, если после настройки лимитов приложение стало падать?
Можно ли определить безопасное число workers только по объёму RAM?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.