Как мы сократили счёт с $800 до €160 — и почти потеряли рассудок (но выжили)
Мы делаем YA — это high-load AI-дневник, который помогает сохранять дни без лишних усилий. Ты фиксируешь мысли, события и настроение в любом формате, а Чат-бот Оракул задаёт короткие вопросы, выделяет главное и показывает инсайты по твоим повторяющимся паттернам. Делается аналитика данных из HealthKit, realtime-агрегациями и собственными AI надстройками. Продукт делали 2 года, в проде — 4 месяца. Активных пользователей с ИИ-фичами сейчас ~40, RPS вырос с 3 до 30–40.
Это история о трёх хостингах, одном CTO-провале сна и нескольких ночных эпических сражениях с Traefik и бэкапами.
Акт I. DigitalOcean — «пока всё помещается»
Начали проект мы просто: один Docker Swarm-узел, несколько droplets, Postgres, Redis, MinIO — и чувство, что «на старте так даже лучше». Счёт ~$400/мес. Радость недолгая.
Получилась как-то раз такая сцена: ночь. Я сижу с чашкой давно остывшего кофе, в телефоне пуш от мониторинга: «IO wait растёт». В логах — строки, похожие на «ну всё, сейчас будет красиво». Проверяю — backup не настроен (тот самый забытый pgbackrest). Мгновение тишины, потом внутренний монолог: «Ладно, копаем дампы, снимки машины, буду руками переносить». В три часа ночи я тащу SQL-дамп по SCP, как недостойный тор мьёльнир, у окна — пустая пачка печенек и строка в терминале: `pg_restore: done`. Спасли — но нерв уже потёрт.
Проблемы были очевидны: CPU не давал нужной отдачи, RAM «вела себя» странно, БД троттлила под нагрузкой — и всё это при росте нагрузки быстро бы переросло в ад.
Акт II. AWS — «мы сделали по-взрослому и переплатили»
Логика была такая: managed-сервисы это меньше забот, больше uptime. Мы переехали на AWS: RDS (3 инстанса), Redis, начальная Kafka, Lambda (1000–3000 вызовов в час), S3, ALB. Результат: комфорт и счёт — $700–950/мес.
Работа шла отлично, все сетки были настроены, авто-масштабирование, CI, канарейки, но спустя пол года: смотрю биллинг в июле — он как ежемесячный счёт за коммуналку, но умноженный на 10.
В онлайн-офисе — короткий разговор с фаундером:
«— Сколько за хостинг? $890?»
«— Видел, нам нравится AWS, но он любит деньги»
«— Ну и что делать?»
Тишина, но понимаю: либо мы сжигаем деньги, либо ищем другой путь.
Как бы плюсы AWS — стабильность и скорость разработки. Но минус — каждый новый managed-сервис добавляет +$ в билл, и в результате выходит что платим облаку зарплату мидла.
Мы сделали анализ, но принять решение вручную оказалось проще — и началась подготовка к дерзкому манёвру.
Акт III. Hetzner — «всё своё и под контролем»
Решение: походить по краю и взять ответственность на себя. Миграция заняла 2–3 дня по 12 часов; один переход дал 8 часов даунтайма. Паника была, но это был контролируемый ад.
Микро-сцена миграции: полночь, меняется DNS, Traefik дергает маршрут — и внезапно часть трафика уходит на стейджинг. В чатике команды — гифка с метнувшимся кабанчиком и сообщение: «Кто переписал маршруты?» Я: «Я» (но без сильной гордости).
Быстро рулю iptables, делаю костыльный перенос через `socat` и молюсь, чтобы не включился cron с очередной рассылкой тестовых писем. В итоге: клиенты не заметили, но я помню запах этого пакета горелых печенек из своей духовки. В какой-то момент я даже подумал взять малинок и купить белый ip, но это прошло как только я поспал.
Что получилось
Архитектура на Hetzner — шесть серверов:
- 2-3 × 16 vCPU / 32 GB — Docker Swarm (основная нагрузка)
- 1 × 4 vCPU / 8 GB — Postgres (Pigsty: Patroni, PgBouncer; single-node сейчас, подготовлено под HA)
- 1 × 4 vCPU / 8 GB — k3s (Kafka + RabbitMQ)
- 1 лёгкая нода — back-office
- 1 dev-нода
Итоговый счёт: €140–160/мес — примерно тройная экономия по сравнению с AWS.
Есть даже веселая ситуация про ClickHouse: он появился только на Hetzner. Я запустил single-node ClickHouse, в прикол назвал таблицу `events_big` и увидел, как агрегации по user-story map начали летать быстрее, чем я успевал писать отчёты. Первый «тяжёлый» запрос вернулся за время, которое позволило мне успеть сделать чай. Маленькая победа.
Почему остался Docker Swarm
Я не мастер k8s — и понимаю, что за переходом на Kubernetes придёт гора поддержки, и нервов, и денег. Поэтому:
- Swarm даёт rolling updates и zero-downtime deploy.
- Наш autoheal — скрипт, который пингует сервис, и если тот не отвечает — делает `docker restart`. Называем его «лечилка» (иногда иронично — «автохилерша»).
- k3s используется точечно для Kafka/RabbitMQ, где нужен побольше контроль.
Была ситуация: autoheal в три часа утра перезапустил сервис и спас день само-копания. Я проснулся от пуша с мониторинга, посмотрел журнал и подумал: «Иногда мои утилиты — братья».
Самый жёсткий момент
Переход AWS -> Hetzner дал нам 8 часов downtime: A/B-сервисы начали падать, терялся кэш, фронт играл в «502». Я помню, как в голове одна мысль: «Если сейчас мы всё потеряем — я верну счёт облаку и уйду в монастырь». Но руками всё переложили без критической потери данных. Паника была — но опыт дороже.
Что стало хуже
- Нервы. Если бы это можно было упаковать в CSV, он бы содержал столбец «кол-во бессонных ночей»
- Ответственность: всё держится на одном человеке — на мне, собьёт электросамокат и до свидания
- Риск ошибок: да, были простои и потерянные куски кэша
Однажды я по невнимательности заблокировал порт RabbitMQ на firewall — очередь стояла, а я в это время пил чай и обсуждали в команде UI-фичу. Очередь подкрутилась, когда я вспомнил про `ufw`. С тех пор чай пью быстро и осторожно.
Что бы я сделал иначе
- Сразу инфраструктурную карту и расчёт точек роста.
- Не держал бы всё в одном Swarm-контексте.
- Подготовил бы HA для БД с самого начала (3 ноды).
- Нанял бы DevOps рано — это сэкономит тысячу нервов.
Итог для тех, кто думает повторить наш путь
Managed == удобство + счёт. Self-hosted == контроль + экономия + бессонные ночи. С экономией €140–160 в месяц нам удалось продлить runway и дать продукту шанс. Но если вы не готовы взять риск и ответственность — подумайте ещё раз.
Мы сэкономили деньги, но я приобрёл 4 года опыта и примерно 10 лет одновременно (шутка). В реальности — это десятки ночей с `scp`, `ansible` и парой крайне нервных коммитов.