Files
admin/.wiki/concepts/on-snolla-vds-deploy-runbook.md
vitya 535ed6170f meta(ruvds): DECOMM 2026-07-21 — powered off, forgotten
ruvds-iis-host (80.64.31.36) decommissioned at provider. Final offsite
snapshot verified on kreknin 2026-07-21 (8.8G, 7-day retention).
Only public domain still on RUVDS was dead rimiz.ru (404 since 2026-05-19);
all snolla-fleet migrated to VDS (stacks 17-22). Local .NET admin
independent of RUVDS. on-snolla runbook rollback-ref updated
(RUVDS no longer rollback-target — image-tag only).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-21 10:14:09 +03:00

9.7 KiB
Raw Permalink Blame History

title, type, tags, related, updated
title type tags related updated
on.snolla.com snolla-app — VDS deploy runbook (cutover 2026-07-20) concept
on-snolla
snolla
vds
deploy
docker
portainer
traefik
runbook
migration
landing
../entities/vds-kzntsv
../entities/ruvds-iis-host
tandemmebel-vds-deploy-runbook
snolla-live-prod-inplace-image-bump
portainer-stack-management-vds
snolla-local-admin-and-on-snolla-migration-design
2026-07-20

on.snolla.com → VDS deploy runbook

Вынос посадочной on.snolla.com (snolla-app, @snollajs/snolla 0.42.1, server-side Liquid) с ../entities/ruvds-iis-host (catch-all CMS, 80.64.31.36) в docker-контейнер на ../entities/vds-kzntsv (89.253.255.94), за traefik. Паттерн = tandemmebel-vds-deploy-runbook. Отличие: лендинг (1 Page /

Артефакты

  • Код: victor/on.snolla.com @ 473923e494db (apps/web, snolla 0.42.1). Структура-калька tandemmebel.ru. deploy/Dockerfile (multi-stage node:22-slim, yarn install --immutable, non-root, healthcheck /robots.txt).
  • Образ: registry.kzntsv.site/on-snolla:473923e494db (+:latest). Имя on-snolla (= стек/контейнер). Собран НА VDS (обход traefik-499).
  • Стек Portainer: on-snolla (Id 22, endpoint 1). Source-of-truth compose: admin/host-stacks/vds-kzntsv/on-snolla.compose.yml.
  • siteId: B9ECDB50-2B93-4CE5-B238-A9918B3F9CF7 (non-secret, в production.json).
  • siteUrl: https://on.snolla.comproduction.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 из tandemmebel стека 20 — общая snolla-инфра). НЕ в образе, НЕ в git.
  • mem_limit: 512m.

Site model (MoreThenCms DB, siteId B9ECDB50)

  • 1 Page / (template content_page, customDefaultLayout=layout). Content-поля пустые → весь bootstraptor-лендинг baked в views/layout.liquid (byte-identical prod). {{ item.content }} (пуст) wired.
  • Form "Join us" (Path /, FormTemplate join_us: first_name/last_name/email/website/description/captcha) baked в layout.liquid; POST / → snolla forms middleware → form_ajax_response.liquid (AJAX replace). Legacy reCAPTCHA v1 в разметке мертва (Google shut down v1) — parity с продом, НЕ чиним.
  • StaticPages: /yandex_7a510ac1f8311fca.html (verification, IncludeInSitemap=true), /4a052808276c.html (not in sitemap).
  • /c404 (stale dead-link в .NET sitemap; snolla-app sitemap тоже его несёт → parity /+/c+/yandex).
  • Theme assets /themes/c406a987ebe14244b0eefe7b8f959a6f/{css,js,images}/* — из MinIO bucket themes (snolla themeFiles middleware; пути literal в layout.liquid).
  • /adminпубличного on.snolla.com/admin не существует (никогда не было: RUVDS catch-all IIS не маршрутизировал /admin на публичном on.snolla.com — cert на 80.64.31.36:443 SNI on.snolla.com = чужой CN=kupimknigi.spb.ru, /admin → 404). Админка — только локальный catch-all IIS snolla (Task A, воркстейшн). Site alias переименован oninternal (2026-07-20), доступ = http://internal.snolla.com/admin через hosts override → 127.0.0.1 → 302→login. Web.config primaryAlias тоже обновлён oninternal (default-site resolution; иначе catch-all NRE-500 на ВСЕХ запросах — primaryAlias ссылается на алиас, переименование сайта без обновления primaryAlias ломает весь catch-all). НЕ часть snolla-app.

Cutover 2026-07-20 (первый вынос на VDS — DNS-gated)

  1. Build на VDS (archive 473923e494db~/build/on-snolladocker build -f deploy/Dockerfile --build-arg VERDACCIO_TOKEN -t .../on-snolla:473923e494db -t .../on-snolla:latest . && push). Guard: config/default.json ABSENT в архиве (.dockerignore), пин snolla = 0.42.1.
  2. Throwaway-staging :5077 из собранного env (8 секретов inline, т.к. нового live-контейнера ещё нет — секреты общие с тиражом). docker run -d --name on-snolla-staging --env-file .staging.env -p 127.0.0.1:5077:5000. Healthy. robots///sitemap 200.
  3. Completeness-gate С VDS — sitemapindex разворот. NEW==PROD locs: 3 = 3 IDENTICAL (/, /c, /yandex_…). Self-consistency: /→200, /yandex→200, /c→404 (dead-link, parity с прод-оракулом — prod /c тоже 404). Byte-parity: homepage + /yandex byte-identical staging vs prod (RUVDS, via --resolve :443:80.64.31.36). GREEN = 0 регрессий.
  4. Portainer стек 22 создан со staging-Host on-snolla.vds.kzntsv.site (wildcard → VDS), LE=default cert. Healthy за traefik. (create-stack.mjs node-скрипт, Portainer JWT auth, env array 8/8, mem_limit 512m.)
  5. DNS flip — operator: reg.ru on.snolla.com A 80.64.31.3689.253.255.94.
  6. Verify авторит. NSnslookup on.snolla.com ns1/ns2.reg.ru = 89.253.255.94 (BEFORE traefik rule swap — memory operator-dns-flip-verify-domain-before-cutover: wrong domain burns LE rate-limit). Public resolvers propagated.
  7. PUT стека 22 — rule Host(on-snolla.vds.kzntsv.site)Host(on.snolla.com), env-preserving (8/8), prune:false, pullImage:false. node cutover-put.mjs (Portainer JWT; re-auth right before PUT — jwt из GET-фазы успел протухнуть к моменту PUT, первый PUT дал 401). PUT 200.
  8. Poll — контейнер healthy, LE-серт issued on first hit: CN=on.snolla.com, issuer YR1, until 2026-10-18.
  9. Live-smoke С VDS + externalhttps://on.snolla.com/{robots.txt,/,/sitemap.xml,/yandex_…} = 200, /c = 404 parity. TLS verify ssl_verify_result=0 (trusted LE chain). Homepage byte-identical prod-HTML.

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

  • snolla robotsTxt middleware падает на undefined app.locals.domain — on.snolla.com НЕ имеет row в MoreThenCms Domains (served by primaryDomain без per-domain row). robotsTxt.js читает res.app.locals.domain.robotsTxt без null-guard → GET /robots.txt (и Dockerfile healthcheck) крашится 500. Фикс в apps/web/index.js: после initApp, если !app.locals.domain, synthesized {robotsTxt: site.robotsTxt} (only robotsTxt.js reads locals.domain; theme resolution uses site.activeThemeId — safe). Без мутации shared DB. Альтернатива (не применена): добавить Domains row (Name=on.snolla.com, SiteId=B9ECDB50, Public=1, ThemeId=null) — но это мутация shared prod MoreThenCms; предпочтён app-code fallback.
  • Form "Join us" не имеет Liquid form-tag — snolla не предоставляет form-rendering tag. Форма HTML baked в layout.liquid (поля по FormTemplate join_us); POST обрабатывает forms middleware (мэтч по Path /). form_ajax_response.liquid — AJAX-ответ ($form.replaceWith(response)).
  • /c в sitemap — dead-link — snolla SitemapService эмбитит /c из sections-source, но страница 404. Prod-оракул идентичен (404) → benign parity, не регрессия.
  • hosts override на воркстейшне — Task A оставил 127.0.0.1 on.snolla.com в hosts (локальный админ catch-all). External verify прод-on.snolla.com с воркстейшна = только через curl --resolve on.snolla.com:443:89.253.255.94 (иначе попадёшь в локальный IIS). См. memory workstation-lan-dns-serves-local-cms-copy.
  • Portainer JWT short-lived — GET stack + GET file + PUT в одном скрипте: jwt из GET-фазы может протухнуть к PUT. Re-auth (POST /api/auth) прямо перед PUT. API-key ptr_* даёт 401 (см. portainer-stack-management-vds).
  • Образных rollback-тегов пока нет — первый deploy, 473923e494db = :latest. Rollback = revert DNS (RUVDS жив). RUVDS DECOMM 2026-07-21 — rollback только образ-тегом.

Rollback

  • DNS (предпочт, мгновенный): revert reg.ru on.snolla.com A → 80.64.31.36 (RUVDS IIS жив, не тронут). НЕАКТУАЛЬНО с 2026-07-21../entities/ruvds-iis-host DECOMM (погашен у провайдера). RUVDS более не rollback-target.
  • Образный (рабочий): PUT стека 22 назад на предыдущий тег (rollback-теги в registry). 473923e494db = :latest — первый deploy, предыдущего тега нет; с этого дня ведём rollback-теги на каждый bump.

Связанное

  • on.snolla.com admin (/admin) остаётся на RUVDS .NET — catch-all IIS snolla (см. snolla-local-admin-and-on-snolla-migration-design §Task A).
  • Тираж snolla на VDS: labtools.ru(17), emspb(18), labtools.pro(19), tandemmebel(20), kupimknigi(21), on-snolla(22).