From 1b2bc61cff6312d877882c8932d374ca089ae0f0 Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Sat, 25 Jul 2026 14:37:08 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20=D1=80=D0=B5=D0=B5=D1=81=D1=82=D1=80=20?= =?UTF-8?q?=D1=83=D0=B1=D1=80=D0=B0=D0=BD=20=D0=B8=D0=B7=20=D0=BE=D0=BF?= =?UTF-8?q?=D0=B8=D1=81=D0=B0=D0=BD=D0=B8=D0=B9,=20=D0=B1=D0=B5=D0=BA?= =?UTF-8?q?=D0=BB=D0=BE=D0=B3=20=D0=BE=D1=82=D0=BC=D0=B5=D1=87=D0=B5=D0=BD?= =?UTF-8?q?=20=D0=BF=D0=BE=20=D0=BB=D0=BE=D0=BA=D0=B0=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D0=BE=D0=B9=20=D1=81=D0=B1=D0=BE=D1=80=D0=BA=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AGENTS.md: homepage/transcriber собираются ролью app_image, registry-плейбуков и vars/transcriber.images.yml больше нет - local-image-build: закрыты шаги по homepage и transcriber, остался вынос yc_*-переменных из vault; добавлены замеры архивов - container-hardening-nits: снят пункт про плавающий `:latest` у homepage --- AGENTS.md | 9 ++++---- docs/backlog/README.md | 2 +- docs/backlog/container-hardening-nits.md | 7 +++--- docs/backlog/local-image-build.md | 27 +++++++++++++----------- 4 files changed, 23 insertions(+), 22 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index ba4fa86..118cf8d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -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-memos.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-rssbridge.yml` — RSS-агрегатор. - `playbook-netdata.yml` — мониторинг. @@ -73,7 +73,7 @@ uv run ansible-galaxy install --role-file requirements.yml - `playbook-goaccess.yml` — аналитика веб-логов Caddy в реальном времени. - `playbook-gramps.yml` — генеалогия. - `playbook-calibre.yml` — управление электронными книгами. -- `playbook-transcriber.yml` — транскрибация (образ из Yandex Registry). +- `playbook-transcriber.yml` — транскрибация (образ собирается локально ролью `app_image`). - `playbook-wanderer.yml` — пешие маршруты. - `playbook-remembos.yml` — интервальное повторение. - `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-applications.yml` — деплой всех приложений. -- `playbook-homepage-registry.yml` / `playbook-transcriber-registry.yml` — загрузка образов в Yandex Registry. - `playbook-remove-user-and-app.yml` — удаление пользователя и приложения (`--extra-vars user_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.` ради подсветки синтаксиса в редакторе. -- Большинство приложений определяют переменные 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`. - Каждое приложение: `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`. diff --git a/docs/backlog/README.md b/docs/backlog/README.md index 28df5d9..6a78bcf 100644 --- a/docs/backlog/README.md +++ b/docs/backlog/README.md @@ -36,7 +36,7 @@ _(sec-ревью)_ — три независимых security-ревью на м - [Уведомления о размере приложений и заполнении диска](disk-usage-alerts.md) — алерты на заполнение диска и аномальный рост data-томов; сервер ресурсно ограничен _(tududi)_ - [Handlers рестарта для оставшихся приложений](handlers-remaining-apps.md) — apprise/dashboard/transcriber/miniflux монтируют конфиг в контейнер, но рестарта нет вовсе; правка конфига не подхватывается - [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 июля цена утечки одной переменной должна быть ограничена одним сервисом - [outline: секреты из файлов](secrets-file-outline.md) — умеет generic `_FILE` для всех пяти секретов; единственное приложение, где выносится вообще всё, включая пароль БД - [wakapi: секреты из файлов](secrets-file-wakapi.md) — salt, SMTP и OIDC выносятся либо через generic `_FILE`, либо через `config.yml`; для OIDC второй путь надёжнее из-за бага с `=` в значении diff --git a/docs/backlog/container-hardening-nits.md b/docs/backlog/container-hardening-nits.md index e220bcc..923cbeb 100644 --- a/docs/backlog/container-hardening-nits.md +++ b/docs/backlog/container-hardening-nits.md @@ -9,10 +9,9 @@ `/root/.gramps`), rssbridge, dozzle, homepage и valkey/postgres-сайдкары gramps. Дотянуть там, где образ позволяет (rssbridge, valkey) — продолжение уже принятой в проекте практики. -- **homepage на `:latest`** (`vars/homepage.yml`) — плавающий тег + ночной `docker - image prune` может подтянуть другое содержимое без отката. Перевести на - иммутабельный `-` по образцу transcriber - (`vars/transcriber.images.yml`). +- ~~**homepage на `:latest`**~~ — **снято**: переход на роль `app_image` + ([local-image-build](local-image-build.md)) дал каждому деплою уникальный тег + из `BUILD_ID`, плавающего `latest` больше нет ни у homepage, ни у остальных. - **Соглашение о портах**: зафиксировать в AGENTS.md, что новые `ports:` — только с `127.0.0.1:`. Docker публикует порты мимо UFW, поэтому дисциплина localhost-биндинга — единственный контроль (сейчас соблюдается: apprise, wanderer). diff --git a/docs/backlog/local-image-build.md b/docs/backlog/local-image-build.md index 9f1ffd6..ab5484d 100644 --- a/docs/backlog/local-image-build.md +++ b/docs/backlog/local-image-build.md @@ -25,33 +25,36 @@ remembos. Схема одинаковая — образ собирается л - ~~завендорить роль `app_image`~~ — **сделано**: подписка в `SYNCED_ROLES`, копия в `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-переменные - из `vars/homepage.yml` + из `vars/homepage.yml`~~ — **сделано**: таск `image` собирает node-образ, сайт + и nginx-образ одной командой; `task deploy`/`deploy-with-ansible` удалены, + деплой целиком — `inv pl -- homepage` - ~~remembos: контракта сборки нет (есть Dockerfile, нет Taskfile) — завести таск `image`, убрать зашитый тег из compose~~ — **сделано**: в репозитории remembos появился `Taskfile.yml` с таском `image`, плейбук зовёт роль, compose тянет `remembos:{{ app_image_tag }}` с `pull_policy: never`; `docker_login` из плейбука убран -- transcriber: исходников на этой машине нет — до начала решить, живой ли сервис - и откуда его собирать; иначе он останется единственным держателем registry и - токен из оборота не выйдет -- убрать `docker_login`-таски и registry-переменные из vault — дальше по - [narrow-secret-scopes](narrow-secret-scopes.md) +- ~~transcriber: исходников на этой машине нет~~ — **сделано**: репозиторий + нашёлся (`~/projects/private/transcriber`), Taskfile сведён к таску `image`, + плейбук переведён на роль; `vars/transcriber.images.yml` с зашитым тегом + удалён вместе с ритуалом «yq + коммит тега» из старого `task deploy` +- осталось: убрать `yc_oauth_token` и `yc_container_registry` из vault — на них + больше никто не ссылается; дальше по [narrow-secret-scopes](narrow-secret-scopes.md) Готово, когда ни один плейбук не делает `docker_login`, `cr.yandex` не встречается в репозитории, а все три приложения деплоятся одним -`inv pl -- `. +`inv pl -- `. Осталось только вычистить vault и прогнать деплой каждого +приложения. Цена размена: дедупликации по слоям больше нет — каждый деплой везёт полный образ, и для сборки нужен локальный docker с тулчейном. Для ручного нечастого -деплоя это осознанный выбор (так решено в самой роли), но у transcriber образ -может оказаться крупным — это стоит проверить до перевода. +деплоя это осознанный выбор (так решено в самой роли). Замеры архивов +(`docker save`): homepage — 61 МБ, transcriber — 73 МБ, remembos — 21 МБ. Пересекается с [gitea-runner-on-demand](gitea-runner-on-demand.md): если сборки уедут в CI, доставка образа на сервер снова становится отдельным вопросом. Связано: playbook-homepage.yml, playbook-transcriber.yml, playbook-remembos.yml, -playbook-homepage-registry.yml, playbook-transcriber-registry.yml, -vars/homepage.yml, vars/transcriber.yml, vars/transcriber.images.yml, +vars/homepage.yml, vars/transcriber.yml, roles/app_image, files/{homepage,transcriber,remembos}/docker-compose.template.yml.