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>
13 KiB
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/snolla0.42.1, читают контент из общей MSSQLMoreThenCmsнаmssql.kzntsv.site:1433+ ассеты из MinIOminio.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-inMoreThenCms.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.com —
dbo.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-настройки.
Шаги
- Verify source (read-only SSH RUVDS, креды
pass show ruvds-iis/full-env):C:\sites\snolla\есть;Web.configнесётstorageType="MoreThenCms.FileStorage.S3.*"+ endpointminio.kzntsv.site; IIS sitesnollaжив. Если MinIO НЕ применён — fallback: build из source + drop-in изMoreThenCms.FileStorage.S3/deploy/(3 DLL +fileStorageClients-s3.sample.config). - Копировать
C:\sites\snolla\RUVDS → локальноC:\sites\snolla\(~8.66 GB; rsync недоступен на Core —scp -rилиrclone copy, resume через rclone). - Репойнт conn-string в локальном
Web.config→Data 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.jsonDB_USER/DB_PASSWORD). - MinIO-ключи в
<fileStorageClients>: endpointhttps://minio.kzntsv.site, бакетыassets/galleries/themes,accessKey/secretKey— изpass show minio-vds/full-env. Если в скопированном Web.config ключи плейсхолдеры__SET_ON_DEPLOY__— подставить реальные. Кэши (imageCache/uploadCache/contentCache/sessionFiles) оставитьLocal. - IIS-сайт
snollaвоссоздать: AppPoolsnolla(.NET v4.0 Integrated,ApplicationPoolIdentity), binding*:80catch-all (как на проде). Локальный доступ гарантируется FW-блоком inbound 80 +hosts-override → 127.0.0.1 (внешние не достучатся). Multi-tenant по Host-header. - ACL:
icacls C:\sites\snolla /grant "IIS AppPool\snolla:(OI)(CI)(M)" /T(паттернsnolla-admin-appdata-acl-500). - 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). - URL Rewrite rule (X-Forwarded-Proto→HTTPS server-vars) — НЕ ставить локально (нет traefik; ходим по http, иначе
:portleak как вcms-server-port-leak-fix). - Firewall: НЕ открывать 80/443 inbound — локальный только.
- 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-allWeb.config→C:\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-fixside-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). Нет репозитория шаблонов+конфига — собираю из боевого сайта + админки.
Реконструкция
- siteId найден:
B9ECDB50-2B93-4CE5-B238-A9918B3F9CF7(aliason, cultureen). - Новый репо
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/snolla0.42.1 (parity с тиражом). - production.json:
siteId=B9ECDB50…,siteUrl=https://on.snolla.com,data.sequelize→MoreThenCmsDBmssql.kzntsv.site:1433(CatalogMoreThenCms),s3→minio.kzntsv.site,imgproxy→imgproxy.kzntsv.site,mediasharp serve-bytes,mailSettings. Секреты в runtime-env стека (Portainer), НЕ в образе/гите — как tandemmebel (8 секретов). - Liquid-шаблоны (views/) — реверс-инжиниринг с боевого
https://on.snolla.com/: для каждой страницы смотрим HTML, сопоставляем с DB-контент-структурой (секции/блоки через локальный админ из Task A), пишемlayout.liquid+ page/partials. Содержимое (текст/картинки) идёт из DB; шаблоны = layout + разметка. Итеративно: пиши шаблон → рендерь на staging → сверяй с боевым HTML (byte/structure parity). - 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 — вероятно простой лендинг, объём шаблонов ограничен.
Последовательность и зависимости
- Task A — восстановить локальный админ (RUVDS→scp→IIS→MinIO→smoke). Блокирует Task B (нужен админ для контент-инспекции).
- 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/контент доступны в общей
MoreThenCmsDB (подтверждено: строка в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-список.