From f5a8a0256aaa9bbf315844cef61ad0a843226a90 Mon Sep 17 00:00:00 2001 From: OpeItcLoc03 Date: Sat, 4 Jul 2026 05:18:05 +0000 Subject: [PATCH] meta(tasks): create [tandemmebel-web-vds-deploy] in OpeItcLoc03/admin --- .tasks/STATUS.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/.tasks/STATUS.md b/.tasks/STATUS.md index 722d936..242b66b 100644 --- a/.tasks/STATUS.md +++ b/.tasks/STATUS.md @@ -1162,3 +1162,47 @@ curl -sI 'https://imgproxy.kzntsv.site/nlXN7RMrer11Fe9XPQaXmq4H0ufzPpo2fOzBWtaL0 --- + +## ⚪ [tandemmebel-web-vds-deploy] — Вынос tandemmebel.ru (snolla-app, `@snollajs/snolla` **0.32.2** / `@snollajs/core` **0.13.8**, server-side Liquid, контент+блог-портфолио+category, БЕЗ e-commerce каталога) с RUVDS IIS на VDS kzntsv (89.253.255.94) за traefik. **Зеркало рунбука `labtools.pro-vds-deploy-runbook`** (модель snolla-тенанта: БД MoreThenCms `mssql.kzntsv.site` + ассеты MinIO через imgproxy). Dev + ДВА полных независимых ре-ревью-раунда + focus watermark-раунд ЗАВЕРШЕНЫ, независимый **PASS**. Это ops-handoff. + +### Артефакты +- **Код:** `victor/tandemmebel.ru` @ `0facb35afde2a966add75e0d603dcf8f16a868af` (master, apps/web). Раунд-2 re-review PASS (byte-parity 9/10, секреты, тесты 22/22, ноль хаков) + focus watermark-раунд PASS (featured-вотермарк=бой, мелкие чисты, cross-tenant чист). `deploy/Dockerfile` (multi-stage node:22-slim, non-root, healthcheck). +- **Образ:** `registry.kzntsv.site/tandemmebel:0facb35` (+`:latest`), собрать **НА VDS** (обход traefik-499). Движок = **snolla@0.32.2 / core@0.13.8**. ⚠️ `content-api` НЕ runtime-dep web-апп (CMS/admin API, консюмер pilorama) — в образ не входит. +- **Стек Portainer:** новый `tandemmebel` (endpoint 1), compose по labtools-pro-шаблону (сменить service/host-имена). Source-of-truth: `admin/host-stacks/vds-kzntsv/tandemmebel.compose.yml`. +- **siteId** `78080707-F6E0-4330-BA30-7922354C2CEF`, activeTheme `EFCD9555-3400-411E-A27D-68D3D8B3DDB2` (theme store MinIO `themes/efcd95553400411ea27d68d3d8b3ddb2/`), Culture **ru-RU**. **siteUrl** `https://www.tandemmebel.ru`. +- **production.json В ПИНЕ содержит** `imgproxy.watermark` override `{size:"post-featured",option:"wm:0.5:ce:0:0:0"}` — уже в образе, отдельно ставить НЕ надо. + +### Runtime env (8 секретов — Portainer stack-env, НЕ в образ/git) +Значения идентичны labtools/emspb/labtools.pro (общий тенант). **Переиспользовать env-массив verbatim из labtools stack (Id 17)** через Portainer API. 8: `DB_USER DB_PASSWORD IMGPROXY_KEY IMGPROXY_SALT S3_ACCESS_KEY_ID S3_SECRET_ACCESS_KEY SMTP_USER SMTP_PASSWORD`. PORT не переопределять (5000; healthcheck; traefik service-port 5000). VERDACCIO_TOKEN build-time only. `config/default.json` исключён `.dockerignore` — проверить ABSENT в архиве. + +### ⚠️ ОБЯЗАТЕЛЬНЫЙ cutover-шаг — PURGE imgproxy-nginx кэша (books-vds) +Focus-ревьюер (независимо) нашёл: nginx перед imgproxy (books-vds, `Cache-Control: max-age=2592000` = 30 дней) закэшировал **ДО-глиф ЧИСТЫЕ** рендеры featured-URL для постов, запрошенных при dev-тестинге (мин. `53-podemnaya-krovat-s-uglovym-shkafom` + smoke-посты). Прод featured-URL детерминированы (без cache-bust) → эти посты отдадут **stale-clean featured (без вотермарка)** в проде до TTL/purge. **ПЕРЕД/НА cutover:** purge nginx-кэш imgproxy на books-vds (стек 29 — cache-dir nginx, напр. `docker exec sh -c 'rm -rf /var/cache/nginx/* && nginx -s reload'`, либо полный purge/redeploy nginx-стека). **Verify после:** свежий featured-URL поста 53 (`.../rs:fill:1170:557:1/g:ce/wm:0.5:ce:0:0:0/...`) → 200 **с вотермарком**. + +### Staging smoke (`tandemmebel.vds.kzntsv.site` vs бой www.tandemmebel.ru; гнать С VDS) +- Status-parity: контент (`/ /prices /vacancies /worksorder /contacts`), category (`/furniture/kitchens`, `/furniture/kitchens/classic`), blog-listing `/projects`, blog-post, `/404` (брендированный, не пустой) — 200/parity. +- **Редиректы:** 65 DB-редиректов, `redirects.test.js` 17/17 vs бой — spot-проверить 301 (target parity modulo host). +- **Sitemap:** snolla index-структура (валидна), все post-URL → 200, 8 постов 2012 = верные даты (core@0.13.8 tz-fix). `/articles` bare-root в sitemap → 404 = **PARITY** с боем (не дефект). +- **Featured с вотермарком** (после cache-purge!), мелкие размеры (thumbs/related/category/hero/og) — чистые. +- theme-ассеты MinIO md5 vs бой под `themes/efcd95553400411ea27d68d3d8b3ddb2/`. +- Контейнер healthy, MSSQL+S3 подключены. + +### Documented benign divergences (НЕ флагать при smoke — 2 раунда ре-ревью подтвердили benign) +1. `/projects` ~10 diff = 2015-ordering isotope (within-date, визуально незаметно). 2. gallery imgproxy vs `/galleries/` direct (URL длиннее, та же картинка 800×800, тот же s3-ключ). 3. sitemap 12× `/projects/categories/*` (200, valid over-inclusion). 4. sitemap index-vs-flat (оба валидны). 5. `/articles` bare-root 404 = parity. + +### Cutover (live DNS) — GATED ОПЕРАТОРОМ +1. (оператор) reg.ru: A `tandemmebel.ru` + `www.tandemmebel.ru` → `89.253.255.94` (с RUVDS). +2. (ops) verify флипа авторитетным NS (`ns1.reg.ru` через Resolve-DnsName) ПЕРЕД traefik. +3. (ops) ТОЛЬКО ПОСЛЕ flip: stack `tandemmebel` traefik-rule → `Host(tandemmebel.ru) || Host(www.tandemmebel.ru)`. Порядок критичен (иначе LE HTTP-01 упадёт на RUVDS → rate-limit). +4. Live-smoke оба хоста + внешняя проверка + **featured-вотермарк на живом**. staging-host убрать из rule. + +### Rollback +DNS → RUVDS IIS (живой, не выводить до явного решения оператора). Стек remove / откат тега. + +**Status:** ready +**Where I stopped:** (not started) +**Next action:** Собрать образ tandemmebel:0facb35 НА VDS → Portainer-стек tandemmebel (env verbatim из labtools stack Id 17) → PURGE imgproxy-nginx кэш (books-vds) → staging-smoke → cutover gated оператором +**Branch:** n/a +**Notify:** OpeItcLoc03/workshop + + +---