bookva MariaDB is published at 89.253.255.133:33306 (0.0.0.0:33306->3306,
port 33306 since 3306 is slovo books-db). Added public DB-endpoints block
to § Доступ (slovo + bookva), noted mongo/ES stay internal, and a
.Ports-vs-.Networks reminder. Closes the port wiki-drift in follow-up #2.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
New entity + inventory source for previously-undocumented family VPN.
Secrets stored separately in pass vdsina-outline/full-env.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4th layer fixed by peer (data 0.9.0->0.9.1). Rebuilt from 6c6d52d
(workspace Dockerfile + sharp @img copy), pushed from VDS, deployed stack 16.
Container smoke all 200: product title<=60 + meta 'доставка по СПб и ЛО';
/catalog/planken 'Планкен прямой и скошенный — купить в СПб'; products 200x3;
home/shipping/blog meta ok. stderr clean. Compose -> 6c6d52d.
Pending (cross-repo, needs push-ok): commit sharp Dockerfile + docker-deploy.md to monorepo.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Dockerfile runner now copies @img (incl sharp-libvips-linux-x64) into .output;
verified SHARP_OK in container. Redeploy: sharp gone, but products 500 from
getSiteById findByPk undefined on snolla 0.17 ecommerce route (pages route OK).
Rolled back to 19a4a84 (all 200). Remaining blocker = snolla/peer zone.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Redeploy from eaee56f: snolla-500 gone, home/categories 200 with SEO,
but sharp native libvips missing in Nitro .output → product listing 500.
Rolled back to 19a4a84 again (catalog works). Platform-specific, peer's
local prod-bundle couldn't catch it.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Build+deploy mechanics solved (workspace Dockerfile, VDS-push for 499).
Prod 500: @snollajs/snolla@0.11.0 getSiteById (Sites model undefined),
nested under content-api@0.11.0 alongside direct snolla@0.16.0.
Rolled back to 19a4a84 (verified 200). Dep fix = web/snolla owner.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
books закрыли named-tag предохранителем (62d812e: protectRe +master|latest).
keep/drop digest-коллизия — снято: keep=1 у books-api это buildcache
(group-by-digest через Map делает keep/drop взаимоисключающими).
Восстановление снесённого named-тега = re-push локального образа с VDS
(docker tag inspect-Image + push под books-ci), не rebuild → плоский
single-platform манифест с .config (pullable, датируется). Применено к
books-api + books-ops-mcp -> :master снова 200. Гоча: books-api вне
CI-матрицы (embed-api-into-web) -> re-push единственный путь.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Первый боевой registryGc dryRun:false (books master-289c660, под добро юзера):
63 DELETE, 0 ошибок, 0x405 -> REGISTRY_STORAGE_DELETE_ENABLED=true подтверждён
живьём; 61 dangling + 2 datable снесены, реестр почищен.
Урок: master у books-api/books-ops-mcp был dangling (не пересобирались ~3нед)
-> логика drop-dangling снесла named-тег -> :master 404. Outage нет (контейнеры
на локальных образах), но redeploy упрётся. Политика: НЕ удалять named-теги
master/latest даже dangling (protectRe -> +master/latest); проверить keep/drop
на digest-коллизию (books-api keep=1 но 0 не-buildcache осталось).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Перепрогон registryGc dryRun на descent-фиксе (master-dcd7c91) вскрыл 2-й
root-cause: реестр засорён dangling OCI image-индексами — тег жив, но его
платформенный sub-manifest отдаёт MANIFEST_UNKNOWN (вычищен прежним host-side
registry garbage-collect, не следящим index->child для multi-arch).
books-web: 19 тегов -> 3 датируемых, 16 dangling.
date-based GC защищает dangling как null-dated -> никогда не удаляет, хотя они
и есть мусор (логика задом наперёд). Рекомендация books: различать
transient-error (protect) vs MANIFEST_UNKNOWN (eligible for delete).
freedBytes от dangling ~0 (слои уже вычищены).
+registry-oci-image-index-gc.md (раздел) +index.md +log.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Следствие закрытия [books-task-runner-registry-auth-cred].
concepts/registry-oci-image-index-gc.md (new): books-* образы в registry =
OCI image-index (buildx), top-level .config=null, дата .created в платформенном
sub-manifest. Наивный GC по top-level дате → null у всех → null-dated группы
защищаются → drop=0 всегда (keepLastN не применяется). Правила: Accept со
всеми media-types, дата из sub, DELETE по index-digest не sub. Зафиксировано
на books registryGc dryRun (deleted=0 при 14 tags) + манифест-dump books-web.
concepts/bindmount-config-edit-preserve-mode.md: дополнен гочей про
bind-mount shadow (config образа затенён целиком → полная секция, не дельта)
+ worked example task-runner (mode не слетел, постмортем сработал).
+index.md (2 строки) +log.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
После deploy нового кода (образ master-bf2a8c5, registryGc v2-DELETE rewrite)
прогнан registryGc {dryRun:true} через scheduler-dispatch (POST /tasks/registryGc
+ x-agenda-job-id): success, 401 нет нигде, repos books-* видны (7 processed),
отчёт сгенерён. Acceptance auth/dryRun met.
Finding отдан books (НЕ блокер кред-таски): GC бежит но drop=0 всегда
(keep=tags-1), keepLastN не применяется — getCreated→null для всех манифестов
(configDigest не извлекается, вероятно OCI image-index от buildx),
planDeletions защищает null-dated группы. Bug в books lib/registryV2.js.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
registry.kzntsv.site is registry:2 + htpasswd Basic (binary access, no
per-repo ACL), NOT Gitea-packages. Added books-ci user (pass
vds-kzntsv/registry-books-ci) for books job-scheduler docker-runner pull.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ingest .wiki/concepts/stostayer-web-deploy-runbook.md — канал деплоя легаси
web (build offline → push docker.stostayer.ru → Portainer-стек 16 через
container-IP API с хоста, мимо Angie BA) + rollback + гоча VPN-IP бан
хостером при retry-push-шторме.
БЛОКЕР задокументирован: легаси packages/web (node16/CJS/Nuxt2) не
пересобрать ни с какого свежего дерева — 5 ESM-ставших депов (@snollajs/snolla,
@snollajs/content-api, @stostayer/api, @stostayer/data ×2). 0.3.18 заморожен.
Фикс формы (120bc07) едет с web4-cutover.
Таска stostayer-web-complaint-form-deploy → 🔵 park (blocker=web4-cutover);
попытка деплоя 0.3.19 откатана на 0.3.18, сайт восстановлен. Дохлый 0.3.19
оставлен в registry по решению vitya.
+ index.md, log.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
redeploy-pilonuxt-gsc-offers closed. Build workstation @37412d0 (verdaccio
build-secret) → push registry.kzntsv.site/pilonuxt:37412d0 → перекат Portainer
stack 16 (PUT API, PullImage). Acceptance: itemprop="offers" (price/currency/
availability/url) на странице товара, verified curl --resolve к VDS; меню+viewModel
200, без регрессии.
Попутно: registry.kzntsv.site зарегистрирован в Portainer (Custom Id 1) —
первый pull падал "no basic auth credentials" (Portainer не имел ни одного
registry; host docker login слетел). Теперь приватный registry авторизован
в Portainer постоянно.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
vitya флипнул DNS pilorama98.ru+www → 89.253.255.94. Перенастроил traefik
роутер на боевые хосты (apex+www+vds-subdomain, LE cert), снял smoke
GTM-override (прод-аналитика вкл), выкатил 125a3e2 (фикс Продукция→/catalog).
Финальный smoke с VDS по www.pilorama98.ru: все страницы page 200/viewModel
200, картинки 200 webp, x-powered-by Nuxt (не IIS), cert valid, битый
футер-линк убран. Форма закрыта (vitya ok + pilonuxt dev-verified).
Stack 16. Задача 🟢 closed. Follow-ups: decommission старого IIS после soak.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
vitya поймал /snolla/pages/viewModel?path=/services -> 500. Перепроверил:
content-api лежит полностью (viewModel 500 на всех путях). Root:
sequelize['snolla'] undefined в content-api → @snollajs/data не
инициализирован (задвоённый stateful-инстанс в Nitro-бандле, класс как
дубль Vue). Каталог работает (app-путь), CMS-страницы нет. Задача обратно
🔵 blocked, cutover отменён. Inbox pilonuxt с диагнозом отправлен.
Урок зафиксирован: smoke = все страницы меню + data-эндпоинты, не 2 роута.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pilonuxt:36ec970 развёрнут Portainer stack 16 на pilonuxt.vds.kzntsv.site.
Инфра зелёная (cert/traefik/egress mssql+smtp/SSR-hairpin). App отдаёт 500
`Cannot read properties of null (reading 'ce')` на всех роутах вкл. server
/api/snolla → баг в data-слое snolla, не деплой. Inbox pilonuxt отправлен.
Blocked на app-фиксе. Стек оставлен поднятым для быстрой итерации тега.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pilonuxt deploy на vds-kzntsv за Traefik. Compose готов (proxy net,
websecure, certresolver letsEncrypt, Host pilonuxt.vds.kzntsv.site, :3000,
GTM погашен на smoke-поддомене). Домен согласован с vitya: temp-поддомен
для smoke, cutover www.pilorama98.ru — отдельным шагом.
Сборка диагностирована, образ НЕ собран — Dockerfile pilonuxt падает в
чистом контейнере (локально замаскировано глоб. yarnrc + сетью):
1. .yarnrc.yml без npmAlwaysAuth:true → YN0041 anonymous (whoami=vitya).
2. Dockerfile не копирует scripts/+src/generated до yarn install →
postinstall Cannot find module scripts/ensure-schema.mjs (YN0009).
По решению vitya сборка отдана pilonuxt (их репо/фикс), за admin — Portainer.
Inbox victor/pilonuxt отправлен с разбором. Задача 🔵 blocked до образа.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Запрос snolla (raw-stream content-api) потребовал MinIO endpoint+креды;
ответ был выводим из вики, но не собран одним куском. Добавлен раздел
«S3 access для клиентских приложений» в minio-imgproxy-on-vds.md:
endpoint (https://minio.kzntsv.site / сырой :9000 / inter minio:9000),
root accessKey + pass-ссылка на secret, форма ключа, ssl/region/pathStyle.
Следующий такой вопрос — grep по вики, без SSH на сервер.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
snolla galleries 404 (imgproxy "Source unreachable"): legacy storageClient
"galleries" = MoreThenCms Local storage class (App_Data\galleries\<siteId>),
never in S3 — products were migrated, galleries weren't. Path A (user pick):
new bucket `galleries`, 301 pilorama98 originals (77 MiB) rclone'd from RUVDS
IIS → s3://galleries/37e6…/<guid>.jpg verbatim. snolla code unchanged
(storageClient=bucket is the working convention). imgproxy smoke from
books-vds: real obj 200 image/webp, fake guid 404. Other sites unmigrated
(scope). Inbox sent to victor/snolla.
- close [migrate-gallery-originals-to-s3] (scope pilorama98)
- NEW .wiki concept galleries-storage-class-local-not-s3
- fix stale minio-imgproxy-on-vds (pipeline on books-vds since 2026-06-08)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>