diff --git a/docs/adr/ADR-2025-05-07-authelia-sso.md b/docs/adr/ADR-2025-05-07-authelia-sso.md new file mode 100644 index 0000000..39074e0 --- /dev/null +++ b/docs/adr/ADR-2025-05-07-authelia-sso.md @@ -0,0 +1,50 @@ +# Authelia вместо Keycloak для SSO + +- Дата: 2025-05-07 + +## Контекст + +Для SSO/OIDC на сервере стоял Keycloak (заведён годом ранее, +2024-05-25). Проблема — ресурсы: Keycloak съедал больше 500 МБ RAM, что +тяжело для личного сервера c ограниченной оперативной памятью. При этом вся его мощь +избыточна: пользователей меньше десяти, realms / federation / тяжёлый +enterprise-стек не нужны. Изначально взял Keycloak, потому что нужен был +OIDC сервер для настройки Outline: когда настраивал был понятный гайд +по OIDC и Keycloak. + +Требовался лёгкий по памяти SSO-провайдер с хорошей документацией, +желательно на Go/Rust. + +## Рассмотренные варианты + +- **Оставить Keycloak.** Отвергнуто: > 500 МБ RAM ради < 10 + пользователей, функционал избыточен для личного сервера. +- **Authelia** (выбран). Лёгкая (Go), малое потребление памяти, хорошая + документация. Умеет и OIDC, и forward-auth. + +Критерии отбора замены: минимальный расход RAM, хорошая документация, +стек Go/Rust. + +## Решение + +Заменили Keycloak на Authelia как провайдер аутентификации +(коммиты `a77fefc`, `d1500ea`, `3a23c08`). Authelia используется в трёх +режимах: + +- **OIDC** для приложений, которым он нужен (например, Outline). +- **Forward-auth** агент в Caddy — удобно там, где полноценный OIDC + избыточен. +- **Закрытие чувствительных приложений** за единым логином. Раньше для + этого использовался basic auth в Caddy. + +## Последствия + +- `+` Резко меньше потребление RAM — критично для сервера с дефицитом + памяти. +- `+` Forward-auth закрывает приложения без OIDC проще, чем поднимать + отдельный OIDC-клиент под каждое. +- `+` Единая точка аутентификации вместо разрозненного basic auth в + Caddy. +- `-` Authelia беднее Keycloak по возможностям (нет полноценного UI + управления пользователями, realms, federation) — но для < 10 + пользователей это не нужно. diff --git a/docs/adr/ADR-2025-12-07-app-data-on-separate-disk.md b/docs/adr/ADR-2025-12-07-app-data-on-separate-disk.md new file mode 100644 index 0000000..bb8831c --- /dev/null +++ b/docs/adr/ADR-2025-12-07-app-data-on-separate-disk.md @@ -0,0 +1,42 @@ +# Данные приложений на отдельном диске + +- Дата: 2025-12-07 + +## Контекст + +Исторически данные приложений лежали прямо в домашних директориях их +системных пользователей (`/home//…`), то есть на системном +диске рядом с ОС. В конце 2025 встал вопрос обновления ОС (Ubuntu 22.04 +уже устарела), и стало ясно: пока данные привязаны к системному диску, +любое обновление или пересборка системы рискует этими данными и тяжело +откатывается. + +Возникла мысль развязать данные приложений и жизненный цикл ОС. + +## Рассмотренные варианты + +- **Данные на системном диске** (как было). Просто, но данные связаны с + ОС: обновление/пересборка системы затрагивает и их. +- **Отдельный диск под данные** (выбран). Данные переживают пересборку + ОС, диск можно отцепить от одного сервера и прицепить к другому. + +## Решение + +Вынесли все данные приложений на отдельный диск, смонтированный в +`/mnt/applications`; каждое приложение держит там свои `data` / `config` +/ `backups`, а `base_dir`/`data_dir` указывают на этот путь +(коммиты `47a6320`, `7e67409`, `ae7c20a`, `8dfd061`). + +## Последствия + +- `+` Данные развязаны с жизненным циклом ОС — систему можно обновлять + и пересобирать, не трогая данные. +- `+` Диск можно отцепить от старого сервера и прицепить к новому. Это + легло в основу метода обновления ОС + ([ADR-2025-12-13](ADR-2025-12-13-os-upgrade-via-server-rebuild.md)). +- `-` Появилась зависимость от монтирования внешнего диска (UUID, + mount-конфигурация): если диск не смонтирован, приложения не + поднимутся. Позже, при переезде в Timeweb, монтирование пришлось + сделать опциональным + ([ADR-2026-05-23](ADR-2026-05-23-migrate-to-timeweb.md), фаза 1 — один + диск, фаза 2 — отдельный «холодный» диск под крупные данные). diff --git a/docs/adr/ADR-2025-12-13-os-upgrade-via-server-rebuild.md b/docs/adr/ADR-2025-12-13-os-upgrade-via-server-rebuild.md new file mode 100644 index 0000000..cccd935 --- /dev/null +++ b/docs/adr/ADR-2025-12-13-os-upgrade-via-server-rebuild.md @@ -0,0 +1,53 @@ +# Обновление ОС пересборкой на свежем сервере + +- Дата: 2025-12-13 + +## Контекст + +На сервере стояла Ubuntu 22.04, и к концу 2025 пора было обновляться. +Обновлять живую боевую систему in-place (`do-release-upgrade`) не +хотелось — это рискованно и тяжело откатывается, если что-то пойдёт не +так на работающем сервере. + +## Рассмотренные варианты + +- **In-place обновление** (`do-release-upgrade` на живой системе). + Отвергнуто: риск сломать рабочий сервер, нет простого отката. +- **Пересборка на свежем сервере** (выбран). Поднять новый сервер с + целевой ОС, накатать ansible, прицепить диск с данными, развернуть + приложения — старый сервер остаётся нетронутым как точка отката. + Заодно почистить мусор от прошлой рабоыт сервера. + +## Решение + +Обновляем ОС через пересборку на свежем сервере. Метод опирается на три +предпосылки: + +- **Деплой без запуска контейнеров.** Сводные плейбуки + (`playbook-all-setup`, `playbook-all-applications`) и тег `run-app` + позволяют раскатать пользователей, каталоги и конфиги, но НЕ запускать + приложения (`--skip-tags run-app`) — данные переносятся в «тихую» + систему (коммиты `5b53cb3`, `48bb8c9`, `67df03e`). +- **Данные на отдельном диске** + ([ADR-2025-12-07](ADR-2025-12-07-app-data-on-separate-disk.md)) — диск + с данными прицепляется к новому серверу. +- **Фиксированные uid/gid.** Заранее закрепили uid/gid всех + пользователей приложений (роль `owner`, коммит `c2ea2cd`). Это + критично: иначе при пересоздании пользователей на новом сервере + uid/gid могли бы сдвинуться, и данные приложений на отдельном диске + оказались бы с чужим владельцем. + +Порядок: сначала вся подготовка (отдельный диск, перенос данных на него, +фиксация uid/gid), затем пересборка на новом обновлённом сервере. Перенос +прошёл без проблем. + +## Последствия + +- `+` Обновление ОС без риска для живой системы; откат = вернуться на + старый сервер. +- `+` Получился воспроизводимый процесс миграции — позже переиспользован + при переезде в Timeweb как «cold cutover» + ([ADR-2026-05-23](ADR-2026-05-23-migrate-to-timeweb.md)). +- `+` Фиксация uid/gid стала постоянным инвариантом проекта. +- `-` Метод требует заранее подготовленных предпосылок (фикс uid/gid + + данные на отдельном диске); без них он не работает. diff --git a/docs/adr/ADR-2026-04-04-apprise-notifications.md b/docs/adr/ADR-2026-04-04-apprise-notifications.md new file mode 100644 index 0000000..f6f51d0 --- /dev/null +++ b/docs/adr/ADR-2026-04-04-apprise-notifications.md @@ -0,0 +1,37 @@ +# Apprise как шлюз нотификаций + +- Дата: 2026-04-04 + +## Контекст + +В первую очередь нужны были нотификации о бэкапах — знать, что ночной +прогон отработал и не сломался. Уведомления слались напрямую в конкретный +канал, привязка была зашита в каждом источнике. Хотелось единый слой, +который абстрагирует каналы доставки — чтобы добавлять или менять канал в +одном месте, а не править каждый источник. + +## Рассмотренные варианты + +- **Прямая интеграция per-канал** (как было). Каждый источник знает про + конкретный канал; смена канала — правки во многих местах. +- **Apprise** (выбран). Смотрел разные self-hosted шлюзы нотификаций; + apprise выиграл зрелостью и числом готовых интеграций (десятки каналов + из коробки). + +## Решение + +Подняли apprise отдельным сервисом-шлюзом: источники шлют уведомление по +HTTP в apprise, а он разводит его по настроенным каналам (коммиты +`a0543e1`, `5f619ea`, `6bfb362`). Под ограниченную память сервера apprise +запущен в один воркер (`5e6df11`). + +## Последствия + +- `+` Каналы доставки абстрагированы за единым шлюзом — добавить или + сменить канал можно в одном месте, не трогая источники. +- `+` Доступ к десяткам интеграций apprise без отдельного кода под + каждую. +- `-` Ещё один сервис в обслуживании (контейнер, память). +- Окупилось при переезде в Timeweb: провайдер заблокировал Telegram, и + переключение нотификаций (сейчас почта, в планах Matrix) локализовано в + шлюзе ([ADR-2026-05-23](ADR-2026-05-23-migrate-to-timeweb.md)). diff --git a/docs/adr/ADR-2026-05-23-migrate-to-timeweb.md b/docs/adr/ADR-2026-05-23-migrate-to-timeweb.md index bf9e180..20ab22a 100644 --- a/docs/adr/ADR-2026-05-23-migrate-to-timeweb.md +++ b/docs/adr/ADR-2026-05-23-migrate-to-timeweb.md @@ -43,7 +43,7 @@ - Стратегия — **cold cutover**: погасить сервисы на источнике, раскатать ansible на новом сервере без запуска приложений (сохраняя uid/gid), перенести данные `rsync`'ом, запустить, переключить DNS. -- Диск: фаза 1 — один 80 ГБ NVMe (всего 22 ГБ данных, влезает с +- Диск: фаза 1 — один 80 ГБ NVMe (всего 22 ГБ данных + 17 ГБ системных, влезает с запасом). «Холодный» второй диск под крупные данные — отдельная фаза 2, не на критическом пути. - Источник не удаляется сразу после cutover: держим «холодным запасным» diff --git a/docs/adr/README.md b/docs/adr/README.md index 5b53874..ce23b44 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -61,7 +61,11 @@ Новые сверху. -| Дата | Запись | Статус | -| ---------- | ------------------------------------------------------------------------------------- | ------ | -| 2026-05-23 | [Переезд сервера с Yandex Cloud на Timeweb VPS](ADR-2026-05-23-migrate-to-timeweb.md) | — | -| 0000-00-00 | [Вести историю решений в виде ADR](ADR-0000-00-00-record-architecture-decisions.md) | — | +| Дата | Запись | Статус | +| ---------- | ---------------------------------------------------------------------------------------------- | ------ | +| 2026-05-23 | [Переезд сервера с Yandex Cloud на Timeweb VPS](ADR-2026-05-23-migrate-to-timeweb.md) | — | +| 2026-04-04 | [Apprise как шлюз нотификаций](ADR-2026-04-04-apprise-notifications.md) | — | +| 2025-12-13 | [Обновление ОС пересборкой на свежем сервере](ADR-2025-12-13-os-upgrade-via-server-rebuild.md) | — | +| 2025-12-07 | [Данные приложений на отдельном диске](ADR-2025-12-07-app-data-on-separate-disk.md) | — | +| 2025-05-07 | [Authelia вместо Keycloak для SSO](ADR-2025-05-07-authelia-sso.md) | — | +| 0000-00-00 | [Вести историю решений в виде ADR](ADR-0000-00-00-record-architecture-decisions.md) | — |