feat(tandemmebel): in-place bump 0.42.0 → 0.42.1 LIVE (stack 20, order-tag fix)

Consumer bump by operator (blocker-pattern 2026-07-04 resolved without dev-source):
pin apps/web/package.json:12 + yarn install (lock 0.42.1/core 0.24.1/liquid 0.10.2/data 0.14.1)
+ commit 0cd9351 + push origin (ls-remote confirmed).

Build on VDS → registry.kzntsv.site/tandemmebel:0cd9351 (digest f29c187f).
Throwaway-staging :5020 from live env, healthy.
Completeness-gate С VDS: 184/184 parity (NEW==PROD), /articles 404 identical to
prod oracle → benign. 0.42.1 order-fix inert on blog-portfolio (no catalog).
Operator-gated PUT stack 20 (env 8/8 preserved, prune:false pullImage:true)
→ container 0cd9351+healthy ~8s. Live-smoke GREEN, TLS cert untouched.

Closes snolla 0.42.1 rollout — all 5 snolla sites now on VDS.
Rollback = tag ed96b18 (+ b02ca18) in registry.

- compose source-of-truth: tag + comment (0.42.1)
- board task: decisions log entry
- wiki: new tandemmebel-vds-deploy-runbook, bump recipe (4 sites), index, log
This commit is contained in:
2026-07-12 13:26:28 +03:00
parent d3d0ff48ed
commit b5839bd02d
6 changed files with 92 additions and 6 deletions

View File

@@ -10,6 +10,7 @@
- `.wiki/concepts/labtools.pro-vds-deploy-runbook.md` — рунбук-зеркало - `.wiki/concepts/labtools.pro-vds-deploy-runbook.md` — рунбук-зеркало
## Decisions log ## Decisions log
- 2026-07-12: **In-place bump 0.42.0→0.42.1 🟢 LIVE.** Поверх cutover'а 2026-07-12 (стек 20 уже боевой, образ ed96b18). Консюмер-бамп сделан оператором сам (пин `apps/web/package.json:12` 0.42.0→0.42.1 + `yarn install` lock + commit `0cd9351` + push origin подтверждён ls-remote — тот же блокер-паттерн 0.42.0 решён без запроса dev-source). Verdaccio: snolla 0.42.1/core 0.24.1/liquid 0.10.2 published (latest). Build на VDS → `registry.kzntsv.site/tandemmebel:0cd9351` (digest f29c187f). Throwaway-staging :5020 из env живого стека, healthy. Completeness-gate С VDS: **184/184 parity** (NEW==PROD, включая 0.42.x sitemap-реструктуризацию), единственный 404 `/articles` идентичен прод-оракулу → benign. Operator-gated PUT стека 20 (env 8/8 сохранён, node put-stack.js, prune:false pullImage:true) → контейнер 0cd9351+healthy за ~8s. Live-smoke GREEN (robots/home/projects/sitemap 200, TLS-серт CN=tandemmebel.ru не дёрнут). 0.42.1 = order-tag Drop-field fix (инертен на этой теме — блог-портфолио без e-commerce каталога, как archive на 0.40→0.42). Rollback = тег ed96b18 в registry (+ b02ca18). Tandemmebel закрывает тираж 0.42.1: теперь ВСЕ 5 snolla-сайтов (labtools.ru/emspb.ru/labtools.pro/kupimknigi+tandemmebel) — kupimknigi+tandemmebel были на 0.42.0, tandemmebel подтянут до 0.42.1.
- 2026-07-04: **CLOSED 🟢.** Staging пересобран на 0.42.0 (ed96b18), оба acceptance-гейта GREEN на новом образе (не унаследованы). Caveat dev-source подтвердился эмпирически: дельта 0.40→0.42 (archive-роуты) инертна на этой теме — completeness 172/172 + gallery 12/12 без диффов. Cutover остаётся отдельным DNS-gated шагом. Follow-up (не блокер): Dockerfile печёт VERDACCIO_TOKEN в ARG/ENV → build-secret (передано dev/workshop). - 2026-07-04: **CLOSED 🟢.** Staging пересобран на 0.42.0 (ed96b18), оба acceptance-гейта GREEN на новом образе (не унаследованы). Caveat dev-source подтвердился эмпирически: дельта 0.40→0.42 (archive-роуты) инертна на этой теме — completeness 172/172 + gallery 12/12 без диффов. Cutover остаётся отдельным DNS-gated шагом. Follow-up (не блокер): Dockerfile печёт VERDACCIO_TOKEN в ARG/ENV → build-secret (передано dev/workshop).
- 2026-07-04: **BLOCKED на входе.** Проверил репо-провенанс: snolla-репо на 0.42.0 (`bcee2d4`, опубликовано), НО tandemmebel.ru origin/master `9fa30a7` пинит `@snollajs/snolla 0.40.0` — консюмер-бамп 0.40→0.42 не закоммичен/не запушен (ни один реф не содержит 0.42/0.24). Byte-verify «199/199 на 0.42.0» из тела таски гонялся против непушнутого локального бампа. Запросил у dev-source (victor/snolla inbox) коммит-бамп + sha. Peer-дисциплина: заявленный state таски ≠ реальность репо → репорт оператору, не проглатывать. - 2026-07-04: **BLOCKED на входе.** Проверил репо-провенанс: snolla-репо на 0.42.0 (`bcee2d4`, опубликовано), НО tandemmebel.ru origin/master `9fa30a7` пинит `@snollajs/snolla 0.40.0` — консюмер-бамп 0.40→0.42 не закоммичен/не запушен (ни один реф не содержит 0.42/0.24). Byte-verify «199/199 на 0.42.0» из тела таски гонялся против непушнутого локального бампа. Запросил у dev-source (victor/snolla inbox) коммит-бамп + sha. Peer-дисциплина: заявленный state таски ≠ реальность репо → репорт оператору, не проглатывать.
- 2026-07-04: Топология A ратифицирована оператором+workshop. Cutover остаётся DNS-gated (внешнее событие). - 2026-07-04: Топология A ратифицирована оператором+workshop. Cutover остаётся DNS-gated (внешнее событие).

View File

@@ -2,8 +2,8 @@
title: snolla live-prod in-place image bump — рецепт (build → staging-acceptance → env-preserving PUT → live-smoke) title: snolla live-prod in-place image bump — рецепт (build → staging-acceptance → env-preserving PUT → live-smoke)
type: concept type: concept
tags: [snolla, vds, deploy, docker, portainer, runbook, recipe, in-place, image-bump, acceptance] tags: [snolla, vds, deploy, docker, portainer, runbook, recipe, in-place, image-bump, acceptance]
related: [[../entities/vds-kzntsv]], [[portainer-stack-management-vds]], [[labtools-vds-deploy-runbook]], [[labtools.pro-vds-deploy-runbook]], [[emspb-vds-deploy-runbook]] related: [[../entities/vds-kzntsv]], [[portainer-stack-management-vds]], [[labtools-vds-deploy-runbook]], [[labtools.pro-vds-deploy-runbook]], [[emspb-vds-deploy-runbook]], [[tandemmebel-vds-deploy-runbook]]
updated: 2026-07-05 updated: 2026-07-12
--- ---
# snolla live-prod in-place image bump # snolla live-prod in-place image bump
@@ -11,6 +11,7 @@ updated: 2026-07-05
Переиспользуемый рецепт для случая: сайт УЖЕ боевой на [[../entities/vds-kzntsv]] в docker-стеке за traefik Переиспользуемый рецепт для случая: сайт УЖЕ боевой на [[../entities/vds-kzntsv]] в docker-стеке за traefik
(cutover сделан ранее), надо **обновить движок/образ на живом стеке in-place** — без staging-first, без DNS-флипа. (cutover сделан ранее), надо **обновить движок/образ на живом стеке in-place** — без staging-first, без DNS-флипа.
Отработан 2026-07-05 на тираже snolla 0.42.1: labtools.ru (стек 17), emspb.ru (18), labtools.pro (19). Отработан 2026-07-05 на тираже snolla 0.42.1: labtools.ru (стек 17), emspb.ru (18), labtools.pro (19).
2026-07-12: tandemmebel.ru (стек 20) — in-place bump 0.42.0→0.42.1 поверх cutover'а того же дня.
Класс риска = **needs-human** (боевой контейнер): боевой swap тега подтверждает оператор ПЕРЕД apply. Класс риска = **needs-human** (боевой контейнер): боевой swap тега подтверждает оператор ПЕРЕД apply.
Отличие от per-site cutover-рунбуков (те про ПЕРВЫЙ вынос на VDS + DNS-флип): здесь домен уже на VDS, Отличие от per-site cutover-рунбуков (те про ПЕРВЫЙ вынос на VDS + DNS-флип): здесь домен уже на VDS,

View File

@@ -0,0 +1,80 @@
---
title: tandemmebel.ru snolla-app — VDS deploy runbook (cutover + in-place 0.42.1 bump)
type: concept
tags: [tandemmebel, snolla, vds, deploy, docker, portainer, traefik, runbook, migration, blog-portfolio]
related: [[../entities/vds-kzntsv]], [[../entities/ruvds-iis-host]], [[portainer-stack-management-vds]], [[minio-imgproxy-on-vds]], [[snolla-live-prod-inplace-image-bump]], [[labtools-vds-deploy-runbook]], [[labtools.pro-vds-deploy-runbook]], [[emspb-vds-deploy-runbook]]
updated: 2026-07-12
---
# tandemmebel.ru → VDS deploy runbook
Вынос `tandemmebel.ru` (snolla-приложение, `@snollajs/snolla` **0.42.1**, server-side Liquid, **блог-портфолио БЕЗ e-commerce каталога**)
с [[../entities/ruvds-iis-host]] (catch-all CMS, 80.64.31.36) в отдельный docker-контейнер на [[../entities/vds-kzntsv]]
(89.253.255.94), за traefik. Модель — snolla-app: читает БД-контент MoreThenCms (`mssql.kzntsv.site`)
+ ассеты из MinIO (`minio.kzntsv.site`). In-process sharp (resize+data-driven watermark), delivery=serve-bytes,
variant-cache бакет в MinIO. imgproxy ИЗ ПУТИ tandem УБРАН (сырой `/imgproxy` → 404 норма).
Паттерн = [[emspb-vds-deploy-runbook]] / [[labtools.pro-vds-deploy-runbook]]. Отличие: **блог-портфолио** (не каталожный →
order-парити секций НЕ применимо — см. 0.42.1 bump ниже). Culture `ru-RU`.
## Артефакты
- **Код:** `victor/tandemmebel.ru` @ `0cd9351` (apps/web, snolla **0.42.1** / core 0.24.1 / liquid 0.10.2 / data 0.14.1).
`deploy/Dockerfile` (multi-stage node:22-slim, `yarn install --immutable`, non-root uid `node`, healthcheck `/robots.txt`).
- **Образ:** `registry.kzntsv.site/tandemmebel:0cd9351` (+`:latest`). Имя **`tandemmebel`** (= имя стека/контейнера).
Собран НА VDS (обход traefik-499). digest `sha256:f29c187fe6114d6ab3926132f4b3eb09df9b606d448cd8fd873780687cb46b8f`.
- **Стек Portainer:** `tandemmebel` (**Id 20**, endpoint 1). Source-of-truth compose: `admin/host-stacks/vds-kzntsv/tandemmebel.compose.yml`.
- **siteId:** `78080707-F6E0-4330-BA30-7922354C2CEF` (non-secret, в `production.json`НЕ env).
- **siteUrl:** `https://www.tandemmebel.ru``production.json`).
- **Runtime env (8 секретов):** `DB_USER DB_PASSWORD IMGPROXY_KEY IMGPROXY_SALT S3_ACCESS_KEY_ID S3_SECRET_ACCESS_KEY SMTP_USER SMTP_PASSWORD` — Portainer stack env (переиспользованы verbatim из labtools стека 17). НЕ в образе, НЕ в git.
- **mem_limit:** `512m` (guardrail; см. [[portainer-stack-management-vds]] § Convention).
## Cutover 2026-07-12 (первый вынос на VDS — DNS-gated)
Последовательность (LE-критичность соблюдена) — см. `NEXT_SESSION.md`:
1. **Verify авторит. NS**`nslookup tandemmebel.ru ns1/ns2.reg.ru` = оба `89.253.255.94` (apex + www), не только резолвер.
2. **GET стек 20** — образ `tandemmebel:ed96b18` (0.42.0, staging cutover-подготовлен), env 8/8, rule staging `Host(tandemmebel.vds.kzntsv.site)`.
3. **PUT стек 20**`Host(tandemmebel.ru) || Host(www.tandemmebel.ru)`, env-preserving, `prune:false, pullImage:false`. Python urllib UTF-8 (НЕ PS Invoke-RestMethod — gotcha кириллицы, см. [[portainer-stack-management-vds]]).
4. **Poll** — контейнер healthy, LE-серт issued on first hit: CN=tandemmebel.ru, SAN оба, issuer YR2, until 2026-10-10.
5. **Live-smoke С VDS** — GREEN.
6. Compose source-of-truth + борд обновлены.
**Латентный прод-баг починен cutover'ом:** `Gotham-Pro.css` был 0B на RUVDS → теперь 200/4436B.
## In-place bump 2026-07-12: 0.42.0 → 0.42.1 (order-tag Drop-field fix)
По рецепту [[snolla-live-prod-inplace-image-bump]] (поверх cutover'а того же дня).
### Консюмер-бамп (решён оператором, без dev-source)
Тот же блокер-паттерн 2026-07-04 (заявленная snolla-версия ≠ консюмер-пин) — на этот раз решён самим оператором:
- `apps/web/package.json:12``0.42.0``0.42.1`.
- `yarn install` в корне монорепы → обновил корневой `yarn.lock` (snolla 0.42.1 / core 0.24.1 / liquid 0.10.2 / data 0.14.1). Dockerfile `yarn install --immutable` — lock обязан совпадать с пином.
- commit `0cd9351` + push origin (git.kzntsv.site/victor/tandemmebel), подтверждён `ls-remote`.
- Тег образа = sha монорепы `0cd9351`.
### Build → staging → gate → swap
1. **Build на VDS** (archive `0cd9351``~/build/tandemmebel``docker build -f deploy/Dockerfile --build-arg VERDACCIO_TOKEN -t .../tandemmebel:0cd9351 -t .../tandemmebel:latest . && push`). Guard: `config/default.json` ABSENT в архиве (.dockerignore), пин = 0.42.1.
2. **Throwaway-staging :5020** из env живого контейнера (`docker inspect tandemmebel``.staging.env`, фильтр `^(HOSTNAME|PATH|NODE_VERSION|YARN_VERSION|HOME)=`). `docker run -d --name tandemmebel-staging --env-file .staging.env -p 127.0.0.1:5020:5000 .../tandemmebel:0cd9351` → healthy. robots.txt+`/`+sitemap 200.
3. **Completeness-gate С VDS** — sitemapindex разворот (`expand()`), два чека:
- **NEW==PROD locs: 184 = 184 IDENTICAL** (вкл. 0.42.x sitemap-реструктуризацию — parity сохранился).
- **self-consistency + content-not-lost** (locs идентичны → один проход): 183×2xx + 1×404.
- Единственный 404 `/articles`**идентичен прод-оракулу** (404 и на live `https://www.tandemmebel.ru/articles`) → benign (пустая секция-без-индекса, не регрессия). Tandemmebel НЕ каталожный → order-парити **не применимо** (0.42.1 order-fix инертен на этой теме — как archive-роуты на 0.40→0.42).
- **GREEN = 0 регрессий в 404/5xx.**
4. **Боевой swap** — operator-gated, node `put-stack.js` (env-preserving: 8/8 name+value, `prune:false, pullImage:true`):
`META=st20.json node put-stack.js 20 1 ed96b18 0cd9351` → PUT 200. Контейнер 0cd9351+healthy за ~8s.
5. **Live-smoke**`https://www.tandemmebel.ru/{robots.txt,/,/projects,/sitemap.xml}` = 200. TLS-серт CN=tandemmebel.ru **не дёрнут** (in-place swap серт не трогает). `docker rm -f tandemmebel-staging`.
### Rollback
- Тег `ed96b18` (0.42.0) в registry (+ `b02ca18`, 0.16.2-staging) → PUT стека 20 назад.
- ИЛИ revert DNS → 80.64.31.36 (RUVDS IIS жив, не тронут — rollback всех мигрированных).
## Гочи (специфичные)
- **Блокер-паттерн консюмер-пина** — snolla-репо релизит версию, но консюмер-пин в tandemmebel-репо отстаёт. На 0.42.0 (2026-07-04) ждали dev-source; на 0.42.1 (2026-07-12) оператор сделал сам. Всегда byte-verify пин+yarn.lock+`ls-remote` перед build.
- **`yarn install --immutable`** в Dockerfile — корневой `yarn.lock` обязан быть снапшотом целевого пина, иначе build падает на checksum-mismatch. Бамп = package.json + `yarn install` (обновляет lock) + commit обоих.
- **0.42.x sitemap-реструктуризация** — parity сверять по **page-locs** (развёрнутый sitemapindex), НЕ по именам под-sitemap'ов. 184 тут (было 172 на 0.42.0 — выросло, но NEW==PROD).
- **`/articles` 404 benign** — loc из sitemap отдаёт 404, если прод-оракул идентичен → не дефект (см. рецепт § Completeness-gate).
- Staging-порт `5020` — проверять `docker ps | grep 127.0.0.1:50` перед bind (stale throwaway от прошлого тиража).
- Smoke гнать **С VDS** (воркстейшн ловит LAN-DNS-перехват прод-доменов — см. memory `workstation-lan-dns-serves-local-cms-copy`).
- build-secret (VERDACCIO_TOKEN в ARG/ENV build-стадии) — известный follow-up, НЕ блокер (runtime-стадия отдельная, токена в финальном образе нет).
## Тираж snolla 0.42.1 — статус
Все 5 snolla-сайтов на VDS:
- labtools.ru (17), emspb.ru (18), labtools.pro (19) — 0.42.1 in-place bump 2026-07-05.
- kupimknigi (21), **tandemmebel (20)** — 0.42.0 cutover, tandemmebel in-place bump до 0.42.1 2026-07-12. (kupimknigi остался на 0.42.0 по решению оператора — см. `NEXT_SESSION.md`.)

View File

@@ -36,6 +36,7 @@ Catalog of all wiki pages. One line per page, organized by type. Updated on ever
- [iis-migration-2026-05-19-postmortem](concepts/iis-migration-2026-05-19-postmortem.md) — post-mortem миграции CMS на нативный IIS, 2026-05-19 - [iis-migration-2026-05-19-postmortem](concepts/iis-migration-2026-05-19-postmortem.md) — post-mortem миграции CMS на нативный IIS, 2026-05-19
- [labtools-vds-deploy-runbook](concepts/labtools-vds-deploy-runbook.md) — labtools.ru snolla-app на VDS (стек 17): сборка/env/cutover 07-02 (Yandex DNS!) + **0.42.1 in-place bump 07-05** (образ `labtools:566d41c`, order-фикс + sitemap починен) - [labtools-vds-deploy-runbook](concepts/labtools-vds-deploy-runbook.md) — labtools.ru snolla-app на VDS (стек 17): сборка/env/cutover 07-02 (Yandex DNS!) + **0.42.1 in-place bump 07-05** (образ `labtools:566d41c`, order-фикс + sitemap починен)
- [labtools.pro-vds-deploy-runbook](concepts/labtools.pro-vds-deploy-runbook.md) — labtools.pro snolla-каталог на VDS (стек 19): сборка/env/cutover 07-02 + **0.42.1 in-place bump 07-05** (образ `labtools-pro:0610432`, order-парити 3 секции) - [labtools.pro-vds-deploy-runbook](concepts/labtools.pro-vds-deploy-runbook.md) — labtools.pro snolla-каталог на VDS (стек 19): сборка/env/cutover 07-02 + **0.42.1 in-place bump 07-05** (образ `labtools-pro:0610432`, order-парити 3 секции)
- [tandemmebel-vds-deploy-runbook](concepts/tandemmebel-vds-deploy-runbook.md) — tandemmebel.ru snolla-блог-портфолио на VDS (стек 20): cutover 07-12 (DNS reg.ru, LE) + **0.42.1 in-place bump 07-12** (образ `tandemmebel:0cd9351`, 184/184 parity, /articles 404 benign)
- [minio-imgproxy-on-vds](concepts/minio-imgproxy-on-vds.md) — MinIO+imgproxy stack на VDS, миграция с upgrade 2020→2025 + DNS swap pending - [minio-imgproxy-on-vds](concepts/minio-imgproxy-on-vds.md) — MinIO+imgproxy stack на VDS, миграция с upgrade 2020→2025 + DNS swap pending
- [morethencms-null-settingsdata-https-502](concepts/morethencms-null-settingsdata-https-502.md) — MoreThenCms тенант с `Sites.SettingsData=NULL` → 502 только на HTTPS (нет `httpSecure` → KeyNotFound); fix = UPDATE + recycle. maljarka 2026-06-08 - [morethencms-null-settingsdata-https-502](concepts/morethencms-null-settingsdata-https-502.md) — MoreThenCms тенант с `Sites.SettingsData=NULL` → 502 только на HTTPS (нет `httpSecure` → KeyNotFound); fix = UPDATE + recycle. maljarka 2026-06-08
- [snolla-admin-appdata-acl-500-after-scp-migration](concepts/snolla-admin-appdata-acl-500-after-scp-migration.md) — админский delete/upload ассета → 500: app pool имел на `App_Data` только RX после scp-миграции → `File.Delete` UnauthorizedAccessException. Fix = icacls Modify. + split-brain: админка пишет Local, боевой app читает MinIO - [snolla-admin-appdata-acl-500-after-scp-migration](concepts/snolla-admin-appdata-acl-500-after-scp-migration.md) — админский delete/upload ассета → 500: app pool имел на `App_Data` только RX после scp-миграции → `File.Delete` UnauthorizedAccessException. Fix = icacls Modify. + split-brain: админка пишет Local, боевой app читает MinIO
@@ -45,7 +46,7 @@ Catalog of all wiki pages. One line per page, organized by type. Updated on ever
- [portainer-2.21-admin-password-regression](concepts/portainer-2.21-admin-password-regression.md) — Portainer 2.21 `--admin-password` regression + min 12-char policy - [portainer-2.21-admin-password-regression](concepts/portainer-2.21-admin-password-regression.md) — Portainer 2.21 `--admin-password` regression + min 12-char policy
- [portainer-stack-management-books-vds](concepts/portainer-stack-management-books-vds.md) — Portainer-managed stacks на books VDS — pattern application + migration log 2026-05-25 - [portainer-stack-management-books-vds](concepts/portainer-stack-management-books-vds.md) — Portainer-managed stacks на books VDS — pattern application + migration log 2026-05-25
- [portainer-stack-management-vds](concepts/portainer-stack-management-vds.md) — Portainer-managed stacks на VDS — canonical pattern + migration script + stack-redeploy recipe (новый тег) + gotchas (вкл. PS 5.1 ISO-8859-1 коррапт кириллицы при API round-trip) - [portainer-stack-management-vds](concepts/portainer-stack-management-vds.md) — Portainer-managed stacks на VDS — canonical pattern + migration script + stack-redeploy recipe (новый тег) + gotchas (вкл. PS 5.1 ISO-8859-1 коррапт кириллицы при API round-trip)
- [snolla-live-prod-inplace-image-bump](concepts/snolla-live-prod-inplace-image-bump.md) — переиспользуемый рецепт обновления образа на ЖИВОМ snolla-стеке VDS in-place (build→throwaway-staging-acceptance С VDS→env-preserving Portainer PUT→live-smoke); вкл. `put-stack.js`; отработан на тираже 0.42.1 - [snolla-live-prod-inplace-image-bump](concepts/snolla-live-prod-inplace-image-bump.md) — переиспользуемый рецепт обновления образа на ЖИВОМ snolla-стеке VDS in-place (build→throwaway-staging-acceptance С VDS→env-preserving Portainer PUT→live-smoke); вкл. `put-stack.js`; отработан на тираже 0.42.1 (4 сайта: labtools/emspb/labtools.pro 2026-07-05 + tandemmebel 2026-07-12)
- [stostayer-web-deploy-runbook](concepts/stostayer-web-deploy-runbook.md) — деплой легаси web (`www.stostayer.ru`) на прод клиента: build→registry→Portainer-стек 16 через container-IP API с хоста; **БЛОКЕР: легаси не пересобрать с master (ESM-стена: top-level await @stostayer/data на build, ERR_REQUIRE_ESM @snollajs/snolla в рантайме)**; гоча — один push без retry (VPN-IP банится хостером) - [stostayer-web-deploy-runbook](concepts/stostayer-web-deploy-runbook.md) — деплой легаси web (`www.stostayer.ru`) на прод клиента: build→registry→Portainer-стек 16 через container-IP API с хоста; **БЛОКЕР: легаси не пересобрать с master (ESM-стена: top-level await @stostayer/data на build, ERR_REQUIRE_ESM @snollajs/snolla в рантайме)**; гоча — один push без retry (VPN-IP банится хостером)
- [proxy-debugging-test-the-real-client](concepts/proxy-debugging-test-the-real-client.md) — анти-паттерн: свои curl/standalone-тесты «работают», а боевой клиент пользователя нет; источник истины — реальный клиент - [proxy-debugging-test-the-real-client](concepts/proxy-debugging-test-the-real-client.md) — анти-паттерн: свои curl/standalone-тесты «работают», а боевой клиент пользователя нет; источник истины — реальный клиент
- [reality-pq-mldsa65-dest-incompatibility](concepts/reality-pq-mldsa65-dest-incompatibility.md) — REALITY+ML-DSA-65 (PQ) не работает с не-PQ dest (Akamai/intel шлёт HRR); fix = PQ-совместимый dest или выключить PQ; **caveat: снятие PQ ≠ рабочий Reality у GUI-клиентов** - [reality-pq-mldsa65-dest-incompatibility](concepts/reality-pq-mldsa65-dest-incompatibility.md) — REALITY+ML-DSA-65 (PQ) не работает с не-PQ dest (Akamai/intel шлёт HRR); fix = PQ-совместимый dest или выключить PQ; **caveat: снятие PQ ≠ рабочий Reality у GUI-клиентов**

View File

@@ -2,6 +2,8 @@
Append-only log of wiki operations (ingests, promotions, lints, migrations). Append-only log of wiki operations (ingests, promotions, lints, migrations).
## [2026-07-12] deploy | tandemmebel.ru in-place bump 0.42.0→0.42.1 LIVE (стек 20) — поверх cutover'а того же дня (стек уже боевой, образ `ed96b18`/0.42.0). Консюмер-бамп сделан оператором сам (тот же блокер-паттерн 0.42.0 2026-07-04 — теперь решён без запроса dev-source): пин `apps/web/package.json:12` 0.42.0→0.42.1 + `yarn install` (lock snolla 0.42.1/core 0.24.1/liquid 0.10.2/data 0.14.1) + commit `0cd9351` + push origin (ls-remote confirmed). Verdaccio: 0.42.1 published (latest). Build на VDS → `registry.kzntsv.site/tandemmebel:0cd9351` (digest f29c187f). Throwaway-staging :5020 из env живого стека, healthy. Completeness-gate С VDS: **184/184 parity** (NEW==PROD, вкл. 0.42.x sitemap-реструктуризацию), единственный 404 `/articles` идентичен прод-оракулу → benign. Operator-gated PUT стека 20 (node put-stack.js, env 8/8 preserve, prune:false pullImage:true) → контейнер 0cd9351+healthy ~8s. Live-smoke GREEN (robots/home/projects/sitemap 200, TLS-серт CN не дёрнут). 0.42.1 = order-tag Drop-field fix, инертен на блог-портфолио (без e-commerce каталога). NEW concepts/tandemmebel-vds-deploy-runbook.md + UPDATE concepts/snolla-live-prod-inplace-image-bump.md (тираж 0.42.1 = 4 in-place bump-сайта) + host-stacks/vds-kzntsv/tandemmebel.compose.yml (тег+комментарий 0.42.1) + index.md. Rollback = тег ed96b18 в registry (+ b02ca18). **Тираж snolla 0.42.1 закрыт полностью.**
## [2026-07-12] deploy | tandemmebel.ru cutover LIVE — последний из тиража snolla 0.42.x. DNS reg.ru `tandemmebel.ru`+`www`→89.253.255.94 (verify ns1/ns2.reg.ru оба), traefik Host-rule staging→боевой на стеке 20 (env 8/8 preserve, prune:false, pullImage:false — образ `ed96b18`/0.42.0 не менялся, без пересборки по решению оператора). LE-серт issued on first hit: CN=tandemmebel.ru, SAN оба, until 2026-10-10. Live-smoke С VDS GREEN: key pages 200, sitemap 184 page-locs, sharp media webp 200, robots из БД. Gotham-Pro.css 0B→4436B (латентный прод-баг починен). Rollback = revert DNS→80.64.31.36 ИЛИ PUT staging-host. UPDATE entities/ruvds-iis-host (tandemmebel→🗑 cutover VDS, биндинги оставлены как rollback) + host-stacks/vds-kzntsv/tandemmebel.compose.yml (rule боевой, заголовок live). **Тираж snolla 0.42.x полностью живой (5/5 стеков на VDS).** ## [2026-07-12] deploy | tandemmebel.ru cutover LIVE — последний из тиража snolla 0.42.x. DNS reg.ru `tandemmebel.ru`+`www`→89.253.255.94 (verify ns1/ns2.reg.ru оба), traefik Host-rule staging→боевой на стеке 20 (env 8/8 preserve, prune:false, pullImage:false — образ `ed96b18`/0.42.0 не менялся, без пересборки по решению оператора). LE-серт issued on first hit: CN=tandemmebel.ru, SAN оба, until 2026-10-10. Live-smoke С VDS GREEN: key pages 200, sitemap 184 page-locs, sharp media webp 200, robots из БД. Gotham-Pro.css 0B→4436B (латентный прод-баг починен). Rollback = revert DNS→80.64.31.36 ИЛИ PUT staging-host. UPDATE entities/ruvds-iis-host (tandemmebel→🗑 cutover VDS, биндинги оставлены как rollback) + host-stacks/vds-kzntsv/tandemmebel.compose.yml (rule боевой, заголовок live). **Тираж snolla 0.42.x полностью живой (5/5 стеков на VDS).**
## [2026-07-03] ingest | NEW concepts/snolla-admin-appdata-acl-500-after-scp-migration — разведка «почему `/admin/assets/<owner>/delete` → 500» на RUVDS IIS. Корень: app pool `IIS AppPool\snolla` (ApplicationPoolIdentity) имел на `C:\sites\snolla\App_Data` только `(RX)` после scp-миграции 23.05 → `File.Delete` в `AssetsService.DeleteAsset` кидает UnauthorizedAccessException → необработанное 500 (event log пуст, IIS substatus 0/win32 0). NRE-версии исключены проверкой строк в БД (Folders root + Files). Fix: `icacls App_Data /grant "IIS AppPool\snolla:(OI)(CI)(M)" /T` (44293 файла, verified `(I)(M)` на таргете). Класс шире delete — все Local-записи из админки (upload/кэши/галереи). Также: заменён `labtools-price.pdf` (owner d375c419) в ОБА хранилища (MinIO `assets/…` ETag→6426ddd0 + локалка IIS, MD5 сверены). Split-brain админка(Local)↔боевой app(MinIO) — cross-ref [[concepts/galleries-storage-class-local-not-s3]]. ## [2026-07-03] ingest | NEW concepts/snolla-admin-appdata-acl-500-after-scp-migration — разведка «почему `/admin/assets/<owner>/delete` → 500» на RUVDS IIS. Корень: app pool `IIS AppPool\snolla` (ApplicationPoolIdentity) имел на `C:\sites\snolla\App_Data` только `(RX)` после scp-миграции 23.05 → `File.Delete` в `AssetsService.DeleteAsset` кидает UnauthorizedAccessException → необработанное 500 (event log пуст, IIS substatus 0/win32 0). NRE-версии исключены проверкой строк в БД (Folders root + Files). Fix: `icacls App_Data /grant "IIS AppPool\snolla:(OI)(CI)(M)" /T` (44293 файла, verified `(I)(M)` на таргете). Класс шире delete — все Local-записи из админки (upload/кэши/галереи). Также: заменён `labtools-price.pdf` (owner d375c419) в ОБА хранилища (MinIO `assets/…` ETag→6426ddd0 + локалка IIS, MD5 сверены). Split-brain админка(Local)↔боевой app(MinIO) — cross-ref [[concepts/galleries-storage-class-local-not-s3]].

View File

@@ -3,7 +3,7 @@
# STAGING-FIRST. Source-of-truth этого compose — admin-репо; применяется через Portainer # STAGING-FIRST. Source-of-truth этого compose — admin-репо; применяется через Portainer
# API/UI (VDS-rule: стеки через Portainer, не ssh+compose). # API/UI (VDS-rule: стеки через Portainer, не ssh+compose).
# #
# Модель: монолит @snollajs/snolla (0.42.0) / @snollajs/core (0.24.0) / data (0.14.1) — читает БД-контент # Модель: монолит @snollajs/snolla (0.42.1) / @snollajs/core (0.24.1) / liquid (0.10.2) / data (0.14.1) — читает БД-контент
# MoreThenCms (mssql.kzntsv.site) + server-side Liquid render. Ассеты из MinIO (minio.kzntsv.site). # MoreThenCms (mssql.kzntsv.site) + server-side Liquid render. Ассеты из MinIO (minio.kzntsv.site).
# МЕДИА: in-process sharp (resize+data-driven watermark), delivery=serve-bytes, cache=local-variant→ # МЕДИА: in-process sharp (resize+data-driven watermark), delivery=serve-bytes, cache=local-variant→
# бакет variant-cache в MinIO. imgproxy ИЗ ПУТИ tandem УБРАН (сырой /imgproxy → 404 норма). # бакет variant-cache в MinIO. imgproxy ИЗ ПУТИ tandem УБРАН (сырой /imgproxy → 404 норма).
@@ -16,9 +16,10 @@
# Домен: LIVE — tandemmebel.ru / www.tandemmebel.ru (cert LE HTTP-01, SAN оба, issued 2026-07-12). # Домен: LIVE — tandemmebel.ru / www.tandemmebel.ru (cert LE HTTP-01, SAN оба, issued 2026-07-12).
# Cutover завершён 2026-07-12: DNS reg.ru → 89.253.255.94 подтверждён на ns1/ns2.reg.ru → # Cutover завершён 2026-07-12: DNS reg.ru → 89.253.255.94 подтверждён на ns1/ns2.reg.ru →
# traefik Host-rule staging→боевой (LE-порядок соблюдён), LE-серт issued on first hit. # traefik Host-rule staging→боевой (LE-порядок соблюдён), LE-серт issued on first hit.
# In-place bump 2026-07-12: 0.42.0→0.42.1 (order-tag Drop-field fix), completeness-gate 184/184 parity GREEN.
# Предыстория: жил на RUVDS IIS (80.64.31.36) до 2026-07-12. # Предыстория: жил на RUVDS IIS (80.64.31.36) до 2026-07-12.
# План отката = revert DNS → 80.64.31.36 (RUVDS IIS жив, не тронут) ИЛИ PUT стека назад на # План отката = revert DNS → 80.64.31.36 (RUVDS IIS жив, не тронут) ИЛИ PUT стека назад на
# Host(`tandemmebel.vds.kzntsv.site`). Образ ed96b18 в registry + b02ca18 (rollback-тег) тоже. # Host(`tandemmebel.vds.kzntsv.site`) + тег ed96b18 (0.42.0). Образ 0cd9351 (0.42.1) — latest; ed96b18 + b02ca18 (rollback-теги) тоже.
# #
# Runtime egress (наружу из proxy-сети): mssql.kzntsv.site:1433, minio.kzntsv.site:443 # Runtime egress (наружу из proxy-сети): mssql.kzntsv.site:1433, minio.kzntsv.site:443
# (оригиналы + запись вариантов в bucket variant-cache), smtp.yandex.ru:465. imgproxy НЕ нужен (sharp in-process). # (оригиналы + запись вариантов в bucket variant-cache), smtp.yandex.ru:465. imgproxy НЕ нужен (sharp in-process).
@@ -31,7 +32,7 @@
services: services:
tandemmebel: tandemmebel:
container_name: tandemmebel container_name: tandemmebel
image: registry.kzntsv.site/tandemmebel:ed96b18 # git-sha victor/tandemmebel.ru master (snolla 0.42.0 / core 0.24.0 / data 0.14.1 — viewmodel-graph + blog-archive) image: registry.kzntsv.site/tandemmebel:0cd9351 # git-sha victor/tandemmebel.ru master (snolla 0.42.1 / core 0.24.1 / liquid 0.10.2 / data 0.14.1 — {% order %} Drop-field fix; in-place bump 2026-07-12). rollback-тег ed96b18 (0.42.0) + b02ca18 в registry.
restart: unless-stopped restart: unless-stopped
mem_limit: 512m # guardrail от runaway: snolla baseline ~100-200M; OOM в контейнере → restart:unless-stopped поднимет. standalone-compose → mem_limit (НЕ deploy.resources — то swarm-only). mem_limit: 512m # guardrail от runaway: snolla baseline ~100-200M; OOM в контейнере → restart:unless-stopped поднимет. standalone-compose → mem_limit (НЕ deploy.resources — то swarm-only).
environment: environment: