Первая версия любого хоумлаба почти всегда выглядит одинаково: есть одна машина, на неё ставится всё подряд, а потом начинается веселье.
Сайт, база данных, музыкальный сервер, тестовый проект, прокси, бот, ещё один контейнер «на пару дней». Через месяц никто уже не помнит, почему половина этого работает именно так.
Я тоже прошёл через желание запустить всё в одном месте. Это удобно ровно до первой серьёзной перезагрузки.
Одна машина — одна большая точка отказа
Когда все сервисы живут вместе, любое обслуживание превращается в событие.
Нужно обновить систему? На паузу встаёт сайт. Экспериментальный контейнер съел память? Страдают вообще все. Что-то сломалось после перезапуска? Теперь надо понять, какой из двадцати компонентов виноват.
Поэтому постепенно я разделил инфраструктуру по ролям.
Не по принципу «каждому контейнеру отдельный сервер» — это уже перебор. Скорее, по характеру задач.
flowchart LR Web["Публичный слой"] --> Build["Сборка и приложения"] Build --> State["Сервисы с данными"] Web --- State
Публичный слой должен быть скучным
Есть часть системы, которая смотрит наружу и принимает запросы к сайту и другим публичным сервисам.
Я специально стараюсь не превращать её в лабораторию. Там лучше держать минимум компонентов и минимум изменений. Публичный вход — не место для эксперимента, который сегодня работает, а завтра внезапно перестал стартовать.
Его задача простая: принять соединение, отдать статику или направить запрос дальше.
Чем скучнее этот слой, тем спокойнее живётся.
Тяжёлые приложения живут отдельно
Дизайн-сервисы, локальные модели, радио, музыкальная библиотека, сборка сайта — это уже другая нагрузка.
Они чаще обновляются, могут занимать много памяти, диска или GPU, а иногда просто ведут себя непредсказуемо. Особенно локальный ИИ: один неудачный запуск модели легко забирает почти весь доступный ресурс.
Поэтому такие вещи логично держать на отдельной машине, которую можно перезапускать и переделывать без падения главной страницы.
Сервисы с состоянием требуют своего внимания
Matrix, базы данных, игровые миры — всё, что хранит постоянное состояние, лучше не мешать с хаотичными экспериментами.
Контейнер можно пересобрать. Мир, история сообщений или база проекта — уже другая история.
Здесь важны резервные копии, понятные каталоги данных и осторожные обновления. Сам контейнер может быть временным. Данные — нет.
Идеальной архитектуры всё равно не получилось
Какие-то связи между машинами остались. Где-то есть исторические решения, которые сейчас я бы сделал иначе. Некоторые сервисы переезжали несколько раз.
Но разделение по ролям уже сильно упрощает жизнь.
Я могу обновить систему с локальными моделями и не переживать за сайт. Могу перезапустить игровой сервис, не затрагивая радио. Могу смотреть на проблему и хотя бы сразу понимать, в какой части инфраструктуры её искать.
Для домашнего проекта этого более чем достаточно.
Конкретные роли перечислены в Серверах, маршрутизация — в Сети, изменения — в Автоматизации.