Add legacy ADR
This commit is contained in:
@@ -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
|
||||||
|
пользователей это не нужно.
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# Данные приложений на отдельном диске
|
||||||
|
|
||||||
|
- Дата: 2025-12-07
|
||||||
|
|
||||||
|
## Контекст
|
||||||
|
|
||||||
|
Исторически данные приложений лежали прямо в домашних директориях их
|
||||||
|
системных пользователей (`/home/<app-user>/…`), то есть на системном
|
||||||
|
диске рядом с ОС. В конце 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 — отдельный «холодный» диск под крупные данные).
|
||||||
@@ -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 +
|
||||||
|
данные на отдельном диске); без них он не работает.
|
||||||
@@ -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)).
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
- Стратегия — **cold cutover**: погасить сервисы на источнике, раскатать
|
- Стратегия — **cold cutover**: погасить сервисы на источнике, раскатать
|
||||||
ansible на новом сервере без запуска приложений (сохраняя uid/gid), перенести
|
ansible на новом сервере без запуска приложений (сохраняя uid/gid), перенести
|
||||||
данные `rsync`'ом, запустить, переключить DNS.
|
данные `rsync`'ом, запустить, переключить DNS.
|
||||||
- Диск: фаза 1 — один 80 ГБ NVMe (всего 22 ГБ данных, влезает с
|
- Диск: фаза 1 — один 80 ГБ NVMe (всего 22 ГБ данных + 17 ГБ системных, влезает с
|
||||||
запасом). «Холодный» второй диск под крупные данные — отдельная
|
запасом). «Холодный» второй диск под крупные данные — отдельная
|
||||||
фаза 2, не на критическом пути.
|
фаза 2, не на критическом пути.
|
||||||
- Источник не удаляется сразу после cutover: держим «холодным запасным»
|
- Источник не удаляется сразу после cutover: держим «холодным запасным»
|
||||||
|
|||||||
+5
-1
@@ -62,6 +62,10 @@
|
|||||||
Новые сверху.
|
Новые сверху.
|
||||||
|
|
||||||
| Дата | Запись | Статус |
|
| Дата | Запись | Статус |
|
||||||
| ---------- | ------------------------------------------------------------------------------------- | ------ |
|
| ---------- | ---------------------------------------------------------------------------------------------- | ------ |
|
||||||
| 2026-05-23 | [Переезд сервера с Yandex Cloud на Timeweb VPS](ADR-2026-05-23-migrate-to-timeweb.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) | — |
|
| 0000-00-00 | [Вести историю решений в виде ADR](ADR-0000-00-00-record-architecture-decisions.md) | — |
|
||||||
|
|||||||
Reference in New Issue
Block a user