docs: реестр убран из описаний, беклог отмечен по локальной сборке

- AGENTS.md: homepage/transcriber собираются ролью app_image, registry-плейбуков
  и vars/transcriber.images.yml больше нет
- local-image-build: закрыты шаги по homepage и transcriber, остался вынос
  yc_*-переменных из vault; добавлены замеры архивов
- container-hardening-nits: снят пункт про плавающий `:latest` у homepage
This commit is contained in:
av
2026-07-25 14:37:08 +03:00
parent fad0d78718
commit 1b2bc61cff
4 changed files with 23 additions and 22 deletions
+4 -5
View File
@@ -2,7 +2,7 @@
## Обзор ## Обзор
Ansible-проект для автоматизации личного сервера. Плейбуки разворачивают докеризированные приложения (gitea, authelia, miniflux, wakapi, memos, outline, gramps, calibre, wanderer, remembos, transcriber и др.) через выделенных системных пользователей, Caddy-прокси и Yandex Docker Registry. Секреты управляются через Ansible Vault. Ansible-проект для автоматизации личного сервера. Плейбуки разворачивают докеризированные приложения (gitea, authelia, miniflux, wakapi, memos, outline, gramps, calibre, wanderer, remembos, transcriber и др.) через выделенных системных пользователей и Caddy-прокси. Секреты управляются через Ansible Vault.
## Структура проекта ## Структура проекта
@@ -65,7 +65,7 @@ uv run ansible-galaxy install --role-file requirements.yml
- `playbook-wakapi.yml` — трекинг времени. - `playbook-wakapi.yml` — трекинг времени.
- `playbook-memos.yml` — заметки. - `playbook-memos.yml` — заметки.
- `playbook-outline.yml` — вики/база знаний. - `playbook-outline.yml` — вики/база знаний.
- `playbook-homepage.yml` — кастомная домашняя страничка на apex `vakhrushev.me` (образ из Yandex Registry). - `playbook-homepage.yml` — кастомная домашняя страничка на apex `vakhrushev.me` (образ собирается локально ролью `app_image`).
- `playbook-dashboard.yml` — дашборд со списком сервисов (gethomepage.dev) на `start.vakhrushev.me`, закрыт за Authelia. - `playbook-dashboard.yml` — дашборд со списком сервисов (gethomepage.dev) на `start.vakhrushev.me`, закрыт за Authelia.
- `playbook-rssbridge.yml` — RSS-агрегатор. - `playbook-rssbridge.yml` — RSS-агрегатор.
- `playbook-netdata.yml` — мониторинг. - `playbook-netdata.yml` — мониторинг.
@@ -73,7 +73,7 @@ uv run ansible-galaxy install --role-file requirements.yml
- `playbook-goaccess.yml` — аналитика веб-логов Caddy в реальном времени. - `playbook-goaccess.yml` — аналитика веб-логов Caddy в реальном времени.
- `playbook-gramps.yml` — генеалогия. - `playbook-gramps.yml` — генеалогия.
- `playbook-calibre.yml` — управление электронными книгами. - `playbook-calibre.yml` — управление электронными книгами.
- `playbook-transcriber.yml` — транскрибация (образ из Yandex Registry). - `playbook-transcriber.yml` — транскрибация (образ собирается локально ролью `app_image`).
- `playbook-wanderer.yml` — пешие маршруты. - `playbook-wanderer.yml` — пешие маршруты.
- `playbook-remembos.yml` — интервальное повторение. - `playbook-remembos.yml` — интервальное повторение.
- `playbook-tuwunel.yml` — Matrix-сервер (Tuwunel) с federation-делегацией на apex-домен. - `playbook-tuwunel.yml` — Matrix-сервер (Tuwunel) с federation-делегацией на apex-домен.
@@ -84,7 +84,6 @@ uv run ansible-galaxy install --role-file requirements.yml
- `playbook-all-setup.yml` — системная настройка целиком (system + docker + eget + backups). - `playbook-all-setup.yml` — системная настройка целиком (system + docker + eget + backups).
- `playbook-all-applications.yml` — деплой всех приложений. - `playbook-all-applications.yml` — деплой всех приложений.
- `playbook-homepage-registry.yml` / `playbook-transcriber-registry.yml` — загрузка образов в Yandex Registry.
- `playbook-remove-user-and-app.yml` — удаление пользователя и приложения (`--extra-vars user_name=<name>`). - `playbook-remove-user-and-app.yml` — удаление пользователя и приложения (`--extra-vars user_name=<name>`).
## Роли ## Роли
@@ -99,7 +98,7 @@ uv run ansible-galaxy install --role-file requirements.yml
## Шаблоны и переменные ## Шаблоны и переменные
- Суффиксы шаблонов: `.template.yml`, `.template.sh`, `.template.cfg`, `.template.conf`, `.template.toml`, `.template` (для файлов без естественного расширения) — рендерятся Ansible модулем `template`. Расширение оригинального формата сохраняется после `.template.` ради подсветки синтаксиса в редакторе. - Суффиксы шаблонов: `.template.yml`, `.template.sh`, `.template.cfg`, `.template.conf`, `.template.toml`, `.template` (для файлов без естественного расширения) — рендерятся Ansible модулем `template`. Расширение оригинального формата сохраняется после `.template.` ради подсветки синтаксиса в редакторе.
- Большинство приложений определяют переменные inline в плейбуке. Отдельные файлы переменных только у homepage и transcriber (`vars/homepage.yml`, `vars/transcriber.yml` + `vars/transcriber.images.yml`). - Большинство приложений определяют переменные inline в плейбуке. Отдельные файлы переменных только у homepage и transcriber (`vars/homepage.yml`, `vars/transcriber.yml`).
- Общие переменные из `group_vars/all/` (`main.yml` + vault-файл `secrets.yml`): `application_dir`, `bin_prefix`, `primary_user` и др. Загружаются автоматически для группы `all`, поэтому плейбуки их не перечисляют. Хост-специфичные значения переопределяются в инвентаре — теперь они имеют приоритет над `group_vars`. - Общие переменные из `group_vars/all/` (`main.yml` + vault-файл `secrets.yml`): `application_dir`, `bin_prefix`, `primary_user` и др. Загружаются автоматически для группы `all`, поэтому плейбуки их не перечисляют. Хост-специфичные значения переопределяются в инвентаре — теперь они имеют приоритет над `group_vars`.
- Каждое приложение: `app_name`, `app_user`, `app_owner_uid`, `app_owner_gid`, `base_dir`, `data_dir`. - Каждое приложение: `app_name`, `app_user`, `app_owner_uid`, `app_owner_gid`, `base_dir`, `data_dir`.
- UID/GID сервисов: новое соглашение — диапазон `11xx`, причём `app_owner_uid == app_owner_gid` (одно число на сервис). Новому приложению берём следующий свободный номер по возрастанию. Старые сервисы ещё сидят на легаси-нумерации `10xx` (часто с разными uid/gid) — их не трогаем, но новые заводим только в `11xx`. - UID/GID сервисов: новое соглашение — диапазон `11xx`, причём `app_owner_uid == app_owner_gid` (одно число на сервис). Новому приложению берём следующий свободный номер по возрастанию. Старые сервисы ещё сидят на легаси-нумерации `10xx` (часто с разными uid/gid) — их не трогаем, но новые заводим только в `11xx`.
+1 -1
View File
@@ -36,7 +36,7 @@ _(sec-ревью)_ — три независимых security-ревью на м
- [Уведомления о размере приложений и заполнении диска](disk-usage-alerts.md) — алерты на заполнение диска и аномальный рост data-томов; сервер ресурсно ограничен _(tududi)_ - [Уведомления о размере приложений и заполнении диска](disk-usage-alerts.md) — алерты на заполнение диска и аномальный рост data-томов; сервер ресурсно ограничен _(tududi)_
- [Handlers рестарта для оставшихся приложений](handlers-remaining-apps.md) — apprise/dashboard/transcriber/miniflux монтируют конфиг в контейнер, но рестарта нет вовсе; правка конфига не подхватывается - [Handlers рестарта для оставшихся приложений](handlers-remaining-apps.md) — apprise/dashboard/transcriber/miniflux монтируют конфиг в контейнер, но рестарта нет вовсе; правка конфига не подхватывается
- [Composable-роль `backup`](ansible-backup-role.md) — бэкап — самый чистый шов для extraction (одинаков у всех, различается только список targets) _(ансибл-ревью)_ - [Composable-роль `backup`](ansible-backup-role.md) — бэкап — самый чистый шов для extraction (одинаков у всех, различается только список targets) _(ансибл-ревью)_
- [Локальная сборка образов вместо Yandex Container Registry](local-image-build.md) — homepage/transcriber/remembos тянут образы из cr.yandex, ради `docker login` в vault лежит OAuth-токен всего аккаунта; роль `app_image` уже обкатана в umbar - [Локальная сборка образов вместо Yandex Container Registry](local-image-build.md) — все три приложения переведены на роль `app_image`; осталось вычистить `yc_*`-переменные из vault и прогнать деплой
- [Вывести из оборота секреты с широкими правами](narrow-secret-scopes.md) — один `yc_oauth_token` открывает весь аккаунт Yandex Cloud; после инцидента 24 июля цена утечки одной переменной должна быть ограничена одним сервисом - [Вывести из оборота секреты с широкими правами](narrow-secret-scopes.md) — один `yc_oauth_token` открывает весь аккаунт Yandex Cloud; после инцидента 24 июля цена утечки одной переменной должна быть ограничена одним сервисом
- [outline: секреты из файлов](secrets-file-outline.md) — умеет generic `<NAME>_FILE` для всех пяти секретов; единственное приложение, где выносится вообще всё, включая пароль БД - [outline: секреты из файлов](secrets-file-outline.md) — умеет generic `<NAME>_FILE` для всех пяти секретов; единственное приложение, где выносится вообще всё, включая пароль БД
- [wakapi: секреты из файлов](secrets-file-wakapi.md) — salt, SMTP и OIDC выносятся либо через generic `_FILE`, либо через `config.yml`; для OIDC второй путь надёжнее из-за бага с `=` в значении - [wakapi: секреты из файлов](secrets-file-wakapi.md) — salt, SMTP и OIDC выносятся либо через generic `_FILE`, либо через `config.yml`; для OIDC второй путь надёжнее из-за бага с `=` в значении
+3 -4
View File
@@ -9,10 +9,9 @@
`/root/.gramps`), rssbridge, dozzle, homepage и valkey/postgres-сайдкары gramps. `/root/.gramps`), rssbridge, dozzle, homepage и valkey/postgres-сайдкары gramps.
Дотянуть там, где образ позволяет (rssbridge, valkey) — продолжение уже принятой Дотянуть там, где образ позволяет (rssbridge, valkey) — продолжение уже принятой
в проекте практики. в проекте практики.
- **homepage на `:latest`** (`vars/homepage.yml`) — плавающий тег + ночной `docker - ~~**homepage на `:latest`**~~ — **снято**: переход на роль `app_image`
image prune` может подтянуть другое содержимое без отката. Перевести на ([local-image-build](local-image-build.md)) дал каждому деплою уникальный тег
иммутабельный `<sha>-<timestamp>` по образцу transcriber из `BUILD_ID`, плавающего `latest` больше нет ни у homepage, ни у остальных.
(`vars/transcriber.images.yml`).
- **Соглашение о портах**: зафиксировать в AGENTS.md, что новые `ports:` — только - **Соглашение о портах**: зафиксировать в AGENTS.md, что новые `ports:` — только
с `127.0.0.1:`. Docker публикует порты мимо UFW, поэтому дисциплина с `127.0.0.1:`. Docker публикует порты мимо UFW, поэтому дисциплина
localhost-биндинга — единственный контроль (сейчас соблюдается: apprise, wanderer). localhost-биндинга — единственный контроль (сейчас соблюдается: apprise, wanderer).
+15 -12
View File
@@ -25,33 +25,36 @@ remembos. Схема одинаковая — образ собирается л
- ~~завендорить роль `app_image`~~ — **сделано**: подписка в `SYNCED_ROLES`, - ~~завендорить роль `app_image`~~ — **сделано**: подписка в `SYNCED_ROLES`,
копия в `roles/app_image`; механика переноса — [shared-roles-sync](shared-roles-sync.md) копия в `roles/app_image`; механика переноса — [shared-roles-sync](shared-roles-sync.md)
- homepage: завести в Taskfile таск `image` с тегом из `$BUILD_ID`, перевести - ~~homepage: завести в Taskfile таск `image` с тегом из `$BUILD_ID`, перевести
плейбук на роль, удалить `playbook-homepage-registry.yml` и registry-переменные плейбук на роль, удалить `playbook-homepage-registry.yml` и registry-переменные
из `vars/homepage.yml` из `vars/homepage.yml`~~ — **сделано**: таск `image` собирает node-образ, сайт
и nginx-образ одной командой; `task deploy`/`deploy-with-ansible` удалены,
деплой целиком — `inv pl -- homepage`
- ~~remembos: контракта сборки нет (есть Dockerfile, нет Taskfile) — завести таск - ~~remembos: контракта сборки нет (есть Dockerfile, нет Taskfile) — завести таск
`image`, убрать зашитый тег из compose~~ — **сделано**: в репозитории remembos `image`, убрать зашитый тег из compose~~ — **сделано**: в репозитории remembos
появился `Taskfile.yml` с таском `image`, плейбук зовёт роль, compose тянет появился `Taskfile.yml` с таском `image`, плейбук зовёт роль, compose тянет
`remembos:{{ app_image_tag }}` с `pull_policy: never`; `docker_login` из `remembos:{{ app_image_tag }}` с `pull_policy: never`; `docker_login` из
плейбука убран плейбука убран
- transcriber: исходников на этой машине нет — до начала решить, живой ли сервис - ~~transcriber: исходников на этой машине нет~~**сделано**: репозиторий
и откуда его собирать; иначе он останется единственным держателем registry и нашёлся (`~/projects/private/transcriber`), Taskfile сведён к таску `image`,
токен из оборота не выйдет плейбук переведён на роль; `vars/transcriber.images.yml` с зашитым тегом
- убрать `docker_login`-таски и registry-переменные из vault — дальше по удалён вместе с ритуалом «yq + коммит тега» из старого `task deploy`
[narrow-secret-scopes](narrow-secret-scopes.md) - осталось: убрать `yc_oauth_token` и `yc_container_registry` из vault — на них
больше никто не ссылается; дальше по [narrow-secret-scopes](narrow-secret-scopes.md)
Готово, когда ни один плейбук не делает `docker_login`, `cr.yandex` не Готово, когда ни один плейбук не делает `docker_login`, `cr.yandex` не
встречается в репозитории, а все три приложения деплоятся одним встречается в репозитории, а все три приложения деплоятся одним
`inv pl -- <app>`. `inv pl -- <app>`. Осталось только вычистить vault и прогнать деплой каждого
приложения.
Цена размена: дедупликации по слоям больше нет — каждый деплой везёт полный Цена размена: дедупликации по слоям больше нет — каждый деплой везёт полный
образ, и для сборки нужен локальный docker с тулчейном. Для ручного нечастого образ, и для сборки нужен локальный docker с тулчейном. Для ручного нечастого
деплоя это осознанный выбор (так решено в самой роли), но у transcriber образ деплоя это осознанный выбор (так решено в самой роли). Замеры архивов
может оказаться крупным — это стоит проверить до перевода. (`docker save`): homepage — 61 МБ, transcriber — 73 МБ, remembos — 21 МБ.
Пересекается с [gitea-runner-on-demand](gitea-runner-on-demand.md): если сборки Пересекается с [gitea-runner-on-demand](gitea-runner-on-demand.md): если сборки
уедут в CI, доставка образа на сервер снова становится отдельным вопросом. уедут в CI, доставка образа на сервер снова становится отдельным вопросом.
Связано: playbook-homepage.yml, playbook-transcriber.yml, playbook-remembos.yml, Связано: playbook-homepage.yml, playbook-transcriber.yml, playbook-remembos.yml,
playbook-homepage-registry.yml, playbook-transcriber-registry.yml, vars/homepage.yml, vars/transcriber.yml, roles/app_image,
vars/homepage.yml, vars/transcriber.yml, vars/transcriber.images.yml,
files/{homepage,transcriber,remembos}/docker-compose.template.yml. files/{homepage,transcriber,remembos}/docker-compose.template.yml.