diff --git a/.tasks/STATUS.md b/.tasks/STATUS.md index 242b66b..6dd9712 100644 --- a/.tasks/STATUS.md +++ b/.tasks/STATUS.md @@ -1,4 +1,5 @@ # Admin Task Board +_Updated: 2026-07-04 (2) — 🟡 **[tandemmebel-web-vds-deploy] STAGING GREEN, ждёт cutover.** Финал тиража tandemmebel. Образ `tandemmebel:0facb35` (snolla@0.32.2/core@0.13.8, digest 464d2f22, watermark-override в пине) собран на VDS (обход 499). Стек Portainer **Id 20** (staging-rule `tandemmebel.vds.kzntsv.site`, env verbatim из labtools стека 17, 8/8), контейнер healthy MSSQL+S3. imgproxy-nginx кэш (books-vds стек 29) purged → featured отдаёт вотермарк без cache-bust (27820B). Staging-smoke с VDS GREEN: status-parity 10/10, sitemap staging⊇prod (prod-only=0, +12 /projects/categories/*=benign#3, /articles 404 parity), trailing 301/301, blog-post 200 (+3.5KB=benign#2 imgproxy vs /galleries/ 26/26), 2012-посты 31/31, theme 21/22 MD5-OK. Находка (не блокер): prod Gotham-Pro.css=0B пустой, staging=4436B корректный → cutover чинит латентный прод-баг шрифта. **HOLD cutover** — жду отмашку оператора на DNS reg.ru→89.253.255.94; порядок: verify авторит.NS → ТОЛЬКО потом боевой Host-rule (иначе LE упадёт на RUVDS). RUVDS=rollback._ _Updated: 2026-07-04 — 🟢 **[imgproxy-watermark-glyph-books-vds] closed.** Ops-подхват по тиражу tandemmebel: воркшоп попросил выставить глиф-вотермарк на imgproxy стек 29 (books-vds). Первый base64 (inbox И закоммиченный таск) был БИТЫЙ на источнике — `tasks_create` порезал 10КБ-поле (sha `f8f0…`≠`e995…`, IEND нет, зацикленный хвост `FQtAlGLzMfBc`×N); поймал sha-сверкой ДО прода (не запушил битьё → imgproxy не упал). Воркшоп до-доставил `logo.png` бинарём в git (`host-stacks/books-vds/tandemmebel-watermark-logo.png`, commit `7127e92a`, sha256 `e995…971fc`, 8015B, IEND ok). PUT стека 29 (Portainer `portainer.kzntsv.site` ep1, X-API-Key, `IMGPROXY_WATERMARK_DATA` inline, `PullImage:false`, БЕЗ глобального `_OPACITY`). Smoke cache-busted: A tandem вотермарк ВИДЕН глазами (27294→27820B); B pilorama контроль byte-identical (160010B) — opacity не просочилась. Notify workshop → tandem-агент на ре-скрин→пин→deploy. Дальше жду `[tandemmebel-web-vds-deploy]`._ _Updated: 2026-07-03 — 🟡 **заведена [morethencms-s3-filestorage-provider].** Разведка «почему /admin/assets/.../delete → 500» на RUVDS IIS: корень = app pool `IIS AppPool\snolla` имел на `App_Data` только RX после scp-миграции → `File.Delete` UnauthorizedAccessException (не MinIO, провайдер `assets`=Local; NRE-версии исключены проверкой строк Folders/Files в БД). Fix применён: `icacls App_Data /grant "IIS AppPool\snolla:(OI)(CI)(M)" /T` (44293 файла, verified). Попутно заменён `labtools-price.pdf` в ОБА хранилища (MinIO ETag→6426ddd0 + локалка, MD5 сверены). Настоящее закрытие split-brain (админка=Local vs фронт=MinIO) → новая таска на S3-провайдер `MoreThenCms.FileStorage.S3` (name approved): ТЗ доставлено в инбокс MoreThenCms, объём=все контентные классы, 1 MinIO, deploy на локальный IIS windows-recovery-host→боевой. DNS-аудит: инфра-хосты не перехватываются (нет 127.0.0.1). Concepts: snolla-admin-appdata-acl-500 + galleries-storage-class-local-not-s3._ _Updated: 2026-06-29 (4) — 🟢 **[pilonuxt-deploy-sitemap-taxonomy] closed.** pilonuxt `6b9ae63` LIVE (стек 16) — bump-only sitemap taxonomy: content-api 0.15→0.16, core 0.2→0.4 (taxonomy enum, прокси не менялся). **Tree-check `.output` 5/5** (content-api 0.16.0, core 0.4.0, data 0.9.1 1×, snolla 0, btoa 0). Push словил **499 на .output** → ретрай прошёл (digest `226584ce…`). Acceptance 4/4: `/sitemap.xml` индекс 7 записей с `store-taxonomy-1`; `/sitemap-store-taxonomy-1.xml`→200 57 url абсолютные (35 categories+22 tags, vendors 0=пусто в CMS); v1 цел (products-1/pages-1 200); `taxonomy-999`→404. Регресс `/`/`/catalog` 200, stderr чист. Откат: стек 16→`42f9d64`. Ack→victor/pilorama98.ru._ @@ -1163,6 +1164,10 @@ curl -sI 'https://imgproxy.kzntsv.site/nlXN7RMrer11Fe9XPQaXmq4H0ufzPpo2fOzBWtaL0 --- +## 🟡 [tandemmebel-web-vds-deploy] — STAGING GREEN 2026-07-04, ждёт cutover (DNS gated оператором). Образ `tandemmebel:0facb35` (digest 464d2f22) собран на VDS; стек Portainer **Id 20** (staging-rule `tandemmebel.vds.kzntsv.site`, env verbatim из стека 17); imgproxy-nginx кэш purged (featured 27820B вотермарк без cache-bust). Smoke с VDS: status-parity 10/10, sitemap staging⊇prod (prod-only=0, +12 /projects/categories/* benign#3), trailing 301/301, blog-post 200 (+3.5KB=benign#2 imgproxy vs /galleries/), 2012-посты 31/31, theme 21/22 MD5-OK. Находка (не блокер): prod Gotham-Pro.css=0B (пустой), staging=4436B корректный → cutover чинит латентный прод-баг шрифта. Следующее: отмашка оператора на DNS → verify авторит.NS → боевой Host-rule в стек 20. + + + ## ⚪ [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. ### Артефакты @@ -1198,11 +1203,12 @@ Focus-ревьюер (независимо) нашёл: nginx перед imgprox ### 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 оператором +**Status:** 🟡 staging-green 2026-07-04, ждёт cutover (DNS gated оператором) +**Where I stopped:** build ✅ (tandemmebel:0facb35 на VDS) + стек Portainer Id 20 (staging-rule) + imgproxy-nginx purge ✅ + staging-smoke GREEN (все гейты, benign #2/3/5 учтены). Uved workshop отправлен. Compose source-of-truth в host-stacks/vds-kzntsv/tandemmebel.compose.yml. +**Next action:** ЖДУ отмашку ОПЕРАТОРА на DNS-флип reg.ru (tandemmebel.ru+www → 89.253.255.94). Потом: verify авторит.NS (Resolve-DnsName) ПЕРЕД traefik → PUT стека 20 rule → Host(`tandemmebel.ru`)||Host(`www.tandemmebel.ru`), убрать staging-host → live-smoke оба хоста + featured-вотермарк на живом. RUVDS=rollback, не трогать. **Branch:** n/a **Notify:** OpeItcLoc03/workshop + --- diff --git a/host-stacks/vds-kzntsv/tandemmebel.compose.yml b/host-stacks/vds-kzntsv/tandemmebel.compose.yml new file mode 100644 index 0000000..63250fa --- /dev/null +++ b/host-stacks/vds-kzntsv/tandemmebel.compose.yml @@ -0,0 +1,59 @@ +# tandemmebel — прод-фронт tandemmebel.ru (snolla-приложение, server-side Liquid, node) на vds-kzntsv (89.253.255.94). +# +# STAGING-FIRST. Source-of-truth этого compose — admin-репо; применяется через Portainer +# API/UI (VDS-rule: стеки через Portainer, не ssh+compose). +# +# Модель: монолит @snollajs/snolla (0.32.2) / @snollajs/core (0.13.8) — читает БД-контент +# MoreThenCms (mssql.kzntsv.site) + server-side Liquid render. Ассеты из MinIO (minio.kzntsv.site) +# через imgproxy (imgproxy.kzntsv.site). node-config: NODE_ENV=production → default(dev,gitignored)+ +# production.json+ENV-override. КОНТЕНТ+БЛОГ-ПОРТФОЛИО+category сайт, БЕЗ e-commerce каталога. +# production.json содержит imgproxy.watermark override {size:post-featured, option:wm:0.5:ce:0:0:0} — в образе. +# +# Образ собирается АДМИНОМ на VDS из victor/tandemmebel.ru/deploy/Dockerfile (build-arg VERDACCIO_TOKEN, +# @snollajs/* из verdaccio.kzntsv.site). Тег = git-sha монорепы tandemmebel.ru (0facb35). +# +# Домен: STAGING — tandemmebel.vds.kzntsv.site (под wildcard *.vds.kzntsv.site, cert LE HTTP-01 авто). +# Cutover live tandemmebel.ru/www.tandemmebel.ru — ОТДЕЛЬНЫЙ gated шаг: бой живой на RUVDS IIS, НЕ выводить. +# DNS переключает ОПЕРАТОР. План отката = revert DNS → 80.64.31.36. +# ⚠️ Host-правило боевых хостов добавлять ТОЛЬКО ПОСЛЕ flip DNS (иначе LE HTTP-01 упадёт на RUVDS → rate-limit). +# +# Runtime egress (наружу из proxy-сети): mssql.kzntsv.site:1433, minio.kzntsv.site:443, +# imgproxy.kzntsv.site:443, smtp.yandex.ru:465. +# +# Секреты — env на VDS (Portainer stack env), НЕ в образ, НЕ в git. Значения ${...} инжектит Portainer +# из stack-переменных (переиспользованы verbatim из labtools stack Id 17). Контракт: +# DB_USER DB_PASSWORD IMGPROXY_KEY IMGPROXY_SALT S3_ACCESS_KEY_ID S3_SECRET_ACCESS_KEY SMTP_USER SMTP_PASSWORD +# siteId=78080707-F6E0-4330-BA30-7922354C2CEF — non-secret, в production.json (не env). Culture ru-RU. siteUrl=https://www.tandemmebel.ru + +services: + tandemmebel: + container_name: tandemmebel + image: registry.kzntsv.site/tandemmebel:0facb35 # git-sha victor/tandemmebel.ru master + restart: unless-stopped + environment: + NODE_ENV: production + TZ: Europe/Moscow + # PORT не переопределяем — образ дефолтит 5000 (EXPOSE 5000, healthcheck на $PORT) + # --- runtime-секреты (значения из Portainer stack env; НЕ хранить тут) --- + DB_USER: ${DB_USER} + DB_PASSWORD: ${DB_PASSWORD} + IMGPROXY_KEY: ${IMGPROXY_KEY} + IMGPROXY_SALT: ${IMGPROXY_SALT} + S3_ACCESS_KEY_ID: ${S3_ACCESS_KEY_ID} + S3_SECRET_ACCESS_KEY: ${S3_SECRET_ACCESS_KEY} + SMTP_USER: ${SMTP_USER} + SMTP_PASSWORD: ${SMTP_PASSWORD} + networks: + - proxy + labels: + traefik.enable: "true" + traefik.http.routers.tandemmebel.entrypoints: websecure + # STAGING-RULE. Cutover: после flip DNS сменить на Host(`tandemmebel.ru`) || Host(`www.tandemmebel.ru`) + # и убрать staging-хост. RUVDS IIS 80.64.31.36 — rollback, не тронут. + traefik.http.routers.tandemmebel.rule: Host(`tandemmebel.vds.kzntsv.site`) + traefik.http.routers.tandemmebel.tls.certresolver: letsEncrypt + traefik.http.services.tandemmebel.loadbalancer.server.port: "5000" + +networks: + proxy: + external: true