Files
admin/.wiki/concepts/snolla-local-admin-and-on-snolla-migration-design.md
vitya b1b0092cdc design(snolla): local .NET admin restore + on.snolla.com VDS migration
Two linked tasks, spec in .wiki/concepts/ per project-discipline.

Task A — snolla-local-admin-restore: восстановить локальный catch-all IIS-сайт
`snolla` (снесён 2026-06-08) копированием C:\sites\snolla\ с RUVDS (прод-админ
с MinIO drop-in), conn → mssql.kzntsv.site MoreThenCms. Доступ
<alias>.snolla.com/admin через hosts-override, один AppPool. Адреса + siteIds
извлечены из MoreThenCms DB read-only.

Task B — on-snolla-vds-migration (blocked by A): on.snolla.com (siteId
B9ECDB50…, alias on, "Internal Site", culture en) с RUVDS IIS → VDS Node
snolla-app 0.42.1, реконструкция Liquid-шаблонов из боевого сайта+админки
(исходников нет). По рецепту tandemmebel-vds-deploy-runbook.

Board entries: .tasks/STATUS.md + per-task files.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-20 09:45:06 +03:00

13 KiB
Raw Permalink Blame History

title: SNOLLA local .NET admin restore + on.snolla.com VDS migration — design type: concept tags: [snolla, morethencms, iis, admin, minio, vds, migration, on-snolla, design] related: ../entities/windows-recovery-host, ../entities/ruvds-iis-host, ../entities/vds-kzntsv, tandemmebel-vds-deploy-runbook, snolla-live-prod-inplace-image-bump, portainer-stack-management-vds, filestorage-s3-provider@MoreThenCms updated: 2026-07-20

SNOLLA local .NET admin restore + on.snolla.com → VDS migration

Две связанные задачи. Task A восстанавливает локальный .NET-админ (чтобы редактировать контент всех сайтов тиража + on.snolla.com). Task B мигрирует посадочную on.snolla.com с RUVDS на VDS как Node snolla-app, реконструируя отсутствующие исходники из боевого сайта + админки. Task A → питает Task B (без рабочего админа не увидеть контент/структуру on.snolla.com).

Контекст

  • Тираж SNOLLA (5 сайтов) уже на VDS как Node snolla-app @snollajs/snolla 0.42.1, читают контент из общей MSSQL MoreThenCms на mssql.kzntsv.site:1433 + ассеты из MinIO minio.kzntsv.site. Стеки Portainer: labtools.ru(17), emspb.ru(18), labtools.pro(19), tandemmebel(20), kupimknigi(21). Публичный snolla-app без админки (apps/web не несёт admin-роутов).
  • На RUVDS IIS (80.64.31.36, Windows Server 2025 Core) остались: catch-all IIS-сайт snolla (MoreThenCms .NET 4.8, /admin для всех *.snolla.com) + посадочная on.snolla.com. МинIO-поддержка в .NET-админ добавлена (drop-in MoreThenCms.FileStorage.S3, см. MoreThenCms .wiki/concepts/filestorage-s3-provider.md).
  • Локальный админ-хост = этот рабочий PC (windows-recovery-host, DESKTOP-NSEF0UK). IIS-сайт snolla + C:\sites\snolla\ были снесены 2026-06-08 (RUVDS забрал прод-админ). Живой локальный аналог остался: stostayer(:8090)/stostayer.old(:8091) — тот же движок MoreThenCms, /admin, conn → mssql.kzntsv.site,1433. Это рабочий шаблон конфига.
  • on.snolla.comdbo.Sites: SiteId=B9ECDB50-2B93-4CE5-B238-A9918B3F9CF7, Alias=on, Title="Internal Site", Culture=en, Live=1, Production=1. Лендинг самого SNOLLA. Отдельного репо/исходников нет.

Task A — восстановить локальный .NET-админ (catch-all IIS snolla)

Адресация (confirmed оператором)

Catch-all IIS-сайт snolla, binding *:80 (локально — 127.0.0.1:80 или *:80 без публикации наружу), один AppPool snolla. Доступ через hosts-override: 127.0.0.1 <alias>.snolla.com на каждый таргет. Multi-tenant routing в CMS по Host-header → siteId из dbo.Sites.

Адреса админок = <Alias>.snolla.com/admin:

Адрес PrimaryDomain siteId
tandemmebel.snolla.com/admin tandemmebel.ru 78080707-F6E0-4330-BA30-7922354C2CEF
labtools.snolla.com/admin labtools.ru D375C419-D787-4FCC-8934-A3B9DC951006
labtoolspro.snolla.com/admin labtools.pro 663F9410-A6CC-4651-9A5C-62844A313957
emspb.snolla.com/admin emspb.ru 96EBC481-D26A-47BE-B660-13D49E7D0A61
kupimknigi.snolla.com/admin kupimknigi.spb.ru E924A354-0377-4E1E-80C6-2EB0194AA55F
on.snolla.com/admin on.snolla.com B9ECDB50-2B93-4CE5-B238-A9918B3F9CF7

Catch-all обслужит /admin для любого сайта из DB при добавлении 127.0.0.1 <alias>.snolla.com в hosts — тираж = 5 + on.snolla.com минимум, при желании все ~60.

Источник C:\sites\snolla\

Рекомендация — копировать с RUVDS (scp/rclone): RUVDS держит C:\sites\snolla\ (8.66 GB) = текущий прод-админ с уже применённым MinIO drop-in. Копируем → получаем админ с MinIO из коробки, без пересборки solution и без ручного патча DLL. Альтернативы (build из MoreThenCms source + применить S3 drop-in вручную; restore с kreknin-backup) дольше и требуют повторной MinIO-настройки.

Шаги

  1. Verify source (read-only SSH RUVDS, креды pass show ruvds-iis/full-env): C:\sites\snolla\ есть; Web.config несёт storageType="MoreThenCms.FileStorage.S3.*" + endpoint minio.kzntsv.site; IIS site snolla жив. Если MinIO НЕ применён — fallback: build из source + drop-in из MoreThenCms.FileStorage.S3/deploy/ (3 DLL + fileStorageClients-s3.sample.config).
  2. Копировать C:\sites\snolla\ RUVDS → локально C:\sites\snolla\ (~8.66 GB; rsync недоступен на Core — scp -r или rclone copy, resume через rclone).
  3. Репойнт conn-string в локальном Web.configData Source=mssql.kzntsv.site,1433;Initial Catalog=MoreThenCms;User ID=<snolla-db-user>;Password=<...>;MultipleActiveResultSets=True;TrustServerCertificate=True (паттерн из stostayer.old/Web.config). DB-креды — из pass (MoreThenCms DB user; тот же, что tandemmebel production.json DB_USER/DB_PASSWORD).
  4. MinIO-ключи в <fileStorageClients>: endpoint https://minio.kzntsv.site, бакеты assets/galleries/themes, accessKey/secretKey — из pass show minio-vds/full-env. Если в скопированном Web.config ключи плейсхолдеры __SET_ON_DEPLOY__ — подставить реальные. Кэши (imageCache/uploadCache/contentCache/sessionFiles) оставить Local.
  5. IIS-сайт snolla воссоздать: AppPool snolla (.NET v4.0 Integrated, ApplicationPoolIdentity), binding *:80 catch-all (как на проде). Локальный доступ гарантируется FW-блоком inbound 80 + hosts-override → 127.0.0.1 (внешние не достучатся). Multi-tenant по Host-header.
  6. ACL: icacls C:\sites\snolla /grant "IIS AppPool\snolla:(OI)(CI)(M)" /T (паттерн snolla-admin-appdata-acl-500).
  7. hosts-override: добавить 127.0.0.1 tandemmebel.snolla.com labtools.snolla.com labtoolspro.snolla.com emspb.snolla.com kupimknigi.snolla.com on.snolla.com в C:\Windows\System32\drivers\etc\hosts (нужен elevation).
  8. URL Rewrite rule (X-Forwarded-Proto→HTTPS server-vars) — НЕ ставить локально (нет traefik; ходим по http, иначе :port leak как в cms-server-port-leak-fix).
  9. Firewall: НЕ открывать 80/443 inbound — локальный только.
  10. Smoke: curl -H "Host: tandemmebel.snolla.com" http://127.0.0.1/admin/account/login → 200 логин-форма; аналогично для on.snolla.com. MinIO: залить тестовый ассет через админку → виден через minio.kzntsv.site/фронтом (приёмка #5 drop-in'а).

Гочи (специфичные)

  • appSettings/sitePath в catch-all Web.configC:\sites\snolla\ (multi-tenant; siteId резолвится из Host-header, не из appSettings — в отличие от per-site stostayer.old где siteId в appSettings).
  • machineKey — оставить из скопированного Web.config (общий для всех tenant'ов админ-сессий).
  • customErrors mode="Off" — обязательно (иначе fatal config error после ASP.NET reload, см. cms-server-port-leak-fix side-regression).
  • MSSQL-коннект с workstation — уже работает (stostayer.old его использует); TrustServerCertificate=True обязательно (mssql.kzntsv.site cert self-signed/не-Microsoft).

Task B — on.snolla.com → VDS (Node snolla-app, реконструкция)

on.snolla.com = MoreThenCms-сайт на RUVDS (посадочная). На VDS (Linux) .NET Framework не бежит → становится Node snolla-app по образцу victor/tandemmebel.ru. Контент (DB-строки + ассеты) уже на vds-kzntsv (общая MoreThenCms DB + MinIO). Нет репозитория шаблонов+конфига — собираю из боевого сайта + админки.

Реконструкция

  1. siteId найден: B9ECDB50-2B93-4CE5-B238-A9918B3F9CF7 (alias on, culture en).
  2. Новый репо victor/on-snolla (имя уточнить у оператора) — структура как tandemmebel.ru: apps/web/{server.js,index.js,config/,views/,package.json}, deploy/Dockerfile (multi-stage node:22-slim, yarn install --immutable, non-root, healthcheck /robots.txt). apps/web/package.json пин @snollajs/snolla 0.42.1 (parity с тиражом).
  3. production.json: siteId=B9ECDB50…, siteUrl=https://on.snolla.com, data.sequelizeMoreThenCms DB mssql.kzntsv.site:1433 (Catalog MoreThenCms), s3minio.kzntsv.site, imgproxyimgproxy.kzntsv.site, media sharp serve-bytes, mailSettings. Секреты в runtime-env стека (Portainer), НЕ в образе/гите — как tandemmebel (8 секретов).
  4. Liquid-шаблоны (views/) — реверс-инжиниринг с боевого https://on.snolla.com/: для каждой страницы смотрим HTML, сопоставляем с DB-контент-структурой (секции/блоки через локальный админ из Task A), пишем layout.liquid + page/partials. Содержимое (текст/картинки) идёт из DB; шаблоны = layout + разметка. Итеративно: пиши шаблон → рендерь на staging → сверяй с боевым HTML (byte/structure parity).
  5. Build на VDS (обход traefik-499), throwaway-staging :50XX, completeness-gate (sitemap parity vs прод-on.snolla.com — page-locs NEW==PROD, self-consistency), stack за traefik (Host(on.snolla.com)), DNS-flip reg.ru→89.253.255.94. По рецепту tandemmebel-vds-deploy-runbook (cutover) + snolla-live-prod-inplace-image-bump (gate). mem_limit 512m.

Trade-off реверс-инжиниринга

Боевой HTML даёт вёрстку, но Liquid-примитивы snolla (sections/blocks/feeds) надо сопоставить с DB-структурой — итеративно. Риск: сложная посадочная с нестандартными блоками = больше итераций. Митигация: on.snolla.com Title="Internal Site" culture en — вероятно простой лендинг, объём шаблонов ограничен.

Последовательность и зависимости

  1. Task A — восстановить локальный админ (RUVDS→scp→IIS→MinIO→smoke). Блокирует Task B (нужен админ для контент-инспекции).
  2. Task B — через локальный админ + боевой HTML собрать on.snolla.com snolla-app → build на VDS → cutover.

Load-bearing допущения (verify в плане)

  • RUVDS C:\sites\snolla\ несёт MinIO drop-in (SSH read-only — первый шаг Task A). Если нет — fallback на build+drop-in.
  • MinIO-ключи в RUVDS Web.config — реальные, не __SET_ON_DEPLOY__ (иначе подтянуть из pass).
  • MoreThenCms DB-креды (snolla-user) в pass — найти путь (кандидаты: mssql-vds/..., общий env). SA-доступ есть (pass show mssql-vds/sa-password) — но админ использует app-аккаунт, не SA; уточнить у оператора.
  • on.snolla.com siteId/контент доступны в общей MoreThenCms DB (подтверждено: строка в dbo.Sites есть).
  • hosts-override + IIS-воссоздание требуют elevation (admin-сессия на workstation).

Rollback

  • Task A: удалить IIS-сайт snolla + C:\sites\snolla\ + откатать hosts-записи. Прод на RUVDS не тронут — rollback = просто не пользоваться локальным админом.
  • Task B: образ предыдущего тега в registry (или RUVDS IIS жив для on.snolla.com пока DNS не флипнут — revert DNS→80.64.31.36).

Open questions (для оператора)

  • Имя нового репо для on.snolla.com (victor/on-snolla? victor/on.snolla.com?).
  • MoreThenCms DB-креды: app-аккаунт + путь в pass (или использовать SA локально / завести отдельный read-write аккаунт).
  • Включать ли в локальный админ ВСЕ сайты (~60) или только тираж(5)+on.snolla.com — catch-all даёт все бесплатно, решает hosts-список.