Self-hosted на 1 ГБ RAM: что реально влезает

Самая дешёвая VPS, один гигабайт и вопрос: это вообще для чего-то годится? Годится. Но придётся выбирать.

Сначала цифра, которая всё определяет. На свежей Ubuntu 24.04 сразу после установки:

$ free -m
               total        used        free      shared  buff/cache   available
Mem:             958         180         520           2         258         640

958 мегабайт «всего» вместо 1024 — часть съело ядро. 180 занято системой. Остаётся примерно 640 мегабайт на всё полезное. Дальше — арифметика и отказы.

Что выкинул сразу

Ревизия «обязательного» стека self-hosted была короткой и безжалостной:

Главный вывод этой ревизии: больше всего памяти съедает не софт, а привычки. Докер тут не потому, что нужен, а потому что «все так делают».

Что осталось и сколько ест

сервисRSSчем написан
nginx~8 МБC
vaultwarden~25 МБRust + SQLite
miniflux~30 МБGo + SQLite
syncthing~60 МБGo
caddy (внутренний прокси)~20 МБGo

Итого около 145 МБ на пять сервисов. Влезает с запасом вдвое. Закономерность видна невооружённым глазом: Rust и Go на SQLite — и всё помещается. Как только появляется отдельная СУБД или рантайм — начинаются проблемы.

zram: единственный настоящий трюк

Swap на диск на дешёвой VPS — это приговор: IOPS там общие с соседями, и при свопинге машина превращается в кирпич. Но swap нужен, иначе OOM-killer приходит за случайной жертвой.

Ответ — zram: сжатый swap в самой памяти. Звучит как парадокс, работает отлично.

apt install zram-tools
# /etc/default/zramswap
ALGO=zstd
PERCENT=50

Полгигабайта zram при zstd даёт реальных 1.2–1.5 ГБ хранимых данных: холодные страницы жмутся в 2.5–3 раза. Скорость — сотни мегабайт в секунду против единиц у диска.

$ zramctl
NAME       ALGORITHM DISKSIZE  DATA COMPR TOTAL STREAMS MOUNTPOINT
/dev/zram0 zstd          479M  312M   98M  104M       1 [SWAP]

312 мегабайт данных занимают 104 мегабайта физической памяти. Чистая прибыль — 200 МБ, то есть треть от изначально доступного. Ради этого стоило.

Не забудьте vm.swappiness. Дефолтные 60 рассчитаны на медленный диск и осторожничают. С zram своп дешёвый, и его надо использовать активнее: vm.swappiness=180 (да, больше 100 — с ядра 5.8 это легально и специально для zram).

earlyoom: страховка

Штатный OOM-killer в Linux включается слишком поздно. К моменту, когда он проснётся, машина уже минут пять как не отвечает на ssh — она занята свопингом. Лечится демоном, который убивает жирного раньше:

apt install earlyoom
# /etc/default/earlyoom
EARLYOOM_ARGS="-m 5 -s 5 --avoid '(^|/)(sshd|systemd)$' --prefer '(^|/)(syncthing)$'"

При падении свободной памяти ниже 5% убивает самое прожорливое, предпочитая syncthing и никогда не трогая sshd. Ключевое здесь — --avoid sshd: машина, куда нельзя зайти, чинится только через панель хостера.

Мелочи, которые дали много

Что в итоге

$ free -m
               total        used        free      shared  buff/cache   available
Mem:             958         524          81         4          543         433
Swap:            479         312         167

Пять сервисов, 433 МБ доступно, аптайм — месяцами. Машина за небольшие деньги делает всё, что мне от неё нужно.

Мораль простая и немного обидная: гигабайта хватает практически на любой домашний self-hosted — при условии, что вы готовы выбирать софт по расходу памяти, а не по популярности. Тот же миниатюрный набор на докере с постгресом не влез бы никуда, делая при этом ровно то же самое.

← все заметки