Первая версия любого хоумлаба почти всегда выглядит одинаково: есть одна машина, на неё ставится всё подряд, а потом начинается веселье.

Сайт, база данных, музыкальный сервер, тестовый проект, прокси, бот, ещё один контейнер «на пару дней». Через месяц никто уже не помнит, почему половина этого работает именно так.

Я тоже прошёл через желание запустить всё в одном месте. Это удобно ровно до первой серьёзной перезагрузки.

Одна машина — одна большая точка отказа

Когда все сервисы живут вместе, любое обслуживание превращается в событие.

Нужно обновить систему? На паузу встаёт сайт. Экспериментальный контейнер съел память? Страдают вообще все. Что-то сломалось после перезапуска? Теперь надо понять, какой из двадцати компонентов виноват.

Поэтому постепенно я разделил инфраструктуру по ролям.

Не по принципу «каждому контейнеру отдельный сервер» — это уже перебор. Скорее, по характеру задач.

flowchart LR
  Web["Публичный слой"] --> Build["Сборка и приложения"]
  Build --> State["Сервисы с данными"]
  Web --- State

Публичный слой должен быть скучным

Есть часть системы, которая смотрит наружу и принимает запросы к сайту и другим публичным сервисам.

Я специально стараюсь не превращать её в лабораторию. Там лучше держать минимум компонентов и минимум изменений. Публичный вход — не место для эксперимента, который сегодня работает, а завтра внезапно перестал стартовать.

Его задача простая: принять соединение, отдать статику или направить запрос дальше.

Чем скучнее этот слой, тем спокойнее живётся.

Тяжёлые приложения живут отдельно

Дизайн-сервисы, локальные модели, радио, музыкальная библиотека, сборка сайта — это уже другая нагрузка.

Они чаще обновляются, могут занимать много памяти, диска или GPU, а иногда просто ведут себя непредсказуемо. Особенно локальный ИИ: один неудачный запуск модели легко забирает почти весь доступный ресурс.

Поэтому такие вещи логично держать на отдельной машине, которую можно перезапускать и переделывать без падения главной страницы.

Сервисы с состоянием требуют своего внимания

Matrix, базы данных, игровые миры — всё, что хранит постоянное состояние, лучше не мешать с хаотичными экспериментами.

Контейнер можно пересобрать. Мир, история сообщений или база проекта — уже другая история.

Здесь важны резервные копии, понятные каталоги данных и осторожные обновления. Сам контейнер может быть временным. Данные — нет.

Идеальной архитектуры всё равно не получилось

Какие-то связи между машинами остались. Где-то есть исторические решения, которые сейчас я бы сделал иначе. Некоторые сервисы переезжали несколько раз.

Но разделение по ролям уже сильно упрощает жизнь.

Я могу обновить систему с локальными моделями и не переживать за сайт. Могу перезапустить игровой сервис, не затрагивая радио. Могу смотреть на проблему и хотя бы сразу понимать, в какой части инфраструктуры её искать.

Для домашнего проекта этого более чем достаточно.

Конкретные роли перечислены в Серверах, маршрутизация — в Сети, изменения — в Автоматизации.