Compare commits
5 Commits
47f24752aa
...
d677f530b4
| Author | SHA1 | Date | |
|---|---|---|---|
| d677f530b4 | |||
| a9f4f3a673 | |||
| ed99f2225b | |||
| 531d7f0fda | |||
| 253f427a55 |
@@ -1,39 +1,47 @@
|
||||
---
|
||||
_last_updated_: 2026-07-02T00:40:00Z
|
||||
session_id: 2026-07-02-emspb-vds-deploy-cutover
|
||||
_last_updated_: 2026-07-02T09:45:00Z
|
||||
session_id: 2026-07-02-labtools-pro-and-ru-vds-cutover
|
||||
---
|
||||
|
||||
# Next session handoff
|
||||
|
||||
## Recent commits
|
||||
- `deploy(emspb)` `c3b722bb`: emspb.ru snolla-app LIVE на vds-kzntsv — staging собран+развёрнут (stack 18) + **cutover выполнен в ту же сессию** (оператор флипнул DNS), live-smoke GREEN. Запушен.
|
||||
- `deploy(labtools)` `a15fd65a`: labtools staging GREEN на vds-kzntsv (stack 17) — ждёт DNS-flip.
|
||||
## Итог сессии — весь snolla-тираж выехал на VDS ✅
|
||||
`emspb.ru` + `labtools.pro` + `labtools.ru` — все LIVE на [[vds-kzntsv]] (`89.253.255.94`) за traefik. RUVDS IIS (`80.64.31.36`) — rollback, живой.
|
||||
|
||||
## Open треки
|
||||
| Трек | Готовность | Entry-point |
|
||||
|---|---|---|
|
||||
| `[labtools-web-vds-deploy]` | STAGING GREEN, **ждём DNS-cutover** | `.tasks/STATUS.md` + `.wiki/concepts/labtools-vds-deploy-runbook.md` |
|
||||
| `[emspb-web-vds-deploy]` | 🟢 **closed** (staging+cutover LIVE) | `.wiki/concepts/emspb-vds-deploy-runbook.md` |
|
||||
## Recent commits (⚠️ 4 ЛОКАЛЬНЫХ, НЕ ЗАПУШЕНЫ — автопуш не выдавался)
|
||||
- `a9f4f3a6` deploy(labtools): 43e28ba LIVE — cutover labtools.ru done
|
||||
- `ed99f222` deploy(labtools-pro): 7bd9fae LIVE — cutover labtools.pro done
|
||||
- `531d7f0f` deploy(labtools-pro): staging GREEN, stack 19
|
||||
- `253f427a` decommission(emspb): сняты emspb.ru/www SNI-биндинги с RUVDS IIS
|
||||
→ **Первое действие след. сессии если разрешат: `git push`** (4 коммита ждут).
|
||||
|
||||
## Состояние emspb (DONE)
|
||||
`emspb.ru`+`www.emspb.ru` LIVE на VDS (`89.253.255.94`), Portainer stack `emspb` (Id 18), образ `registry.kzntsv.site/emspb:b6e361a`. traefik-rule = боевые хосты (staging-хост убран→404), единый LE-cert, `ssl_verify=0`. RUVDS IIS `80.64.31.36` цел = rollback. Env == labtools (8 секретов). Рунбук записан. Workshop отрепорчен.
|
||||
## Состояние треков
|
||||
| Трек | Статус | Стек | Образ |
|
||||
|---|---|---|---|
|
||||
| `[emspb-web-vds-deploy]` | 🟢 closed (LIVE + RUVDS decommissioned) | 18 | emspb:b6e361a |
|
||||
| `[labtools-pro-web-vds-deploy]` | 🟢 closed (LIVE) | 19 | labtools-pro:7bd9fae |
|
||||
| `[labtools-web-vds-deploy]` | 🟢 closed (LIVE) | 17 | labtools:43e28ba |
|
||||
|
||||
## Состояние labtools (ЖДЁТ)
|
||||
Образ `registry.kzntsv.site/labtools:43e28ba`, Portainer stack `labtools` (Id 17), STAGING `labtools.vds.kzntsv.site` healthy, smoke vs бой GREEN. Бой на RUVDS IIS (`80.64.31.36`) живой. **DNS labtools.ru/www ВСЁ ЕЩЁ на RUVDS** (проверено 2026-07-02 внешним резолвером) — cutover НЕ выполнен.
|
||||
Рунбуки: `.wiki/concepts/{emspb,labtools,labtools.pro}-vds-deploy-runbook.md`.
|
||||
|
||||
## Спроси оператора / жди сигнал
|
||||
- **labtools DNS-cutover** — как оператор скажет «флипнул labtools» (проверить внешним резолвером что именно labtools→VDS!): добавить в stack 17 traefik-rule `Host(labtools.ru) || Host(www.labtools.ru)`, дождаться LE-cert, smoke на боевом хосте, убрать staging-хост post-cutover, отрепортить. Рунбук labtools § Cutover.
|
||||
- `labtools.pro` — отдельная таска, ждёт заведения (оператор решил 2026-07-01).
|
||||
## DNS-факты (на будущее)
|
||||
- Зоны на РАЗНЫХ провайдерах: `emspb.ru`/`labtools.pro` — **reg.ru** (`ns1/ns2.reg.ru`); `labtools.ru` — **Yandex DNS** (`dns1/dns2.yandex.net`). Проверять авторитетный NS того провайдера.
|
||||
- labtools.ru siteUrl = **non-www** (`https://labtools.ru`, sitemap host без www); emspb/labtools.pro = www (R3). Разные тенанты — разный canonical.
|
||||
|
||||
## Не делать (guards)
|
||||
- **НЕ добавлять `Host(labtools.ru)` в traefik-rule ДО флипа DNS** — LE HTTP-01 упадёт на RUVDS → сожжём rate-limit. Cм. memory [operator-dns-flip-verify-domain-before-cutover].
|
||||
- **НЕ путать домены** — на этой сессии оператор флипнул emspb, НЕ labtools (был запланирован). Всегда external-resolve перед PUT traefik-rule.
|
||||
- **НЕ выводить RUVDS IIS** (labtools/emspb) — rollback-путь.
|
||||
- **НЕ флипать DNS самим** — это оператор.
|
||||
- Build snolla-образов — НА VDS из чистого `git archive`, push с VDS (registry локален).
|
||||
## Открытые follow-up (не блокеры, по решению оператора)
|
||||
- **RUVDS-биндинги labtools.ru/www + labtools.pro/www** ещё на IIS (rollback). Снять как для emspb (`Remove-WebBinding` + backup config) — когда оператор скажет. Ключ: `~/.ssh/ruvds-iis-migration`, `Administrator@80.64.31.36`. См. [[../.wiki/entities/ruvds-iis-host]].
|
||||
- **`emspb.snolla.com`** — НЕ мигрирован (DNS→IIS), биндинг оставлен намеренно. Отдельная миграция если понадобится.
|
||||
- **www.labtools.ru** — на момент wrap ещё split-brain (публичный кэш RUVDS, TTL до 6ч); авторитетные оба уже VDS, LE-cert на www выпущен. Доедет сам. Спот-чек внешним резолвером позже.
|
||||
- **Косметика labtools.pro:** стартовый баннер лога = `labtools.ru (snolla)` (константа app-name из скаффолда). У workshop, не блокер.
|
||||
|
||||
## Autopush
|
||||
- Оператор выдал grant «пуш разрешаю» на этой сессии (2026-07-02). Session-end сбрасывает в ask-mode.
|
||||
## Guards
|
||||
- RUVDS IIS НЕ выводить целиком (общий catch-all, ещё держит ~22 хоста + rollback).
|
||||
- НЕ добавлять `Host(...)` в traefik ДО подтверждения флипа на **всех** авторитетных NS зоны (LE rate-limit).
|
||||
- Стеки на VDS — только через Portainer (env сохранять при PUT, pullImage=false для label-only правок).
|
||||
|
||||
## Инфра-заметки
|
||||
- Сборка образов — на VDS из `git archive <sha>` (обход traefik-499), push с VDS. VERDACCIO_CI_TOKEN + PORTAINER_API_KEY в `pass vds-kzntsv/full-env`.
|
||||
- Env всех snolla-тенантов идентичен (8 секретов) — при новом стеке брать verbatim из соседнего (`GET /api/stacks/<id>|.Env`).
|
||||
|
||||
## Memory updates за сессию
|
||||
- Заведена `operator-dns-flip-verify-domain-before-cutover` (verify which domain externally before touching traefik Host rule).
|
||||
- Дополнена `operator-dns-flip-verify-domain-before-cutover`: проверять АВТОРИТЕТНЫЙ NS (не публичный кэш), гейт = ВСЕ auth-NS согласны (dns1/dns2 расходятся mid-propagation), идентифицировать провайдера зоны.
|
||||
|
||||
@@ -989,7 +989,7 @@ deps подняты: `@snollajs/snolla ^0.18`, `content-api ^0.13`, `content-api
|
||||
|
||||
---
|
||||
|
||||
## 🟡 [labtools-web-vds-deploy] — Деплой `labtools.ru` snolla-приложения (`victor/labtools.ru/apps/web`) в docker-контейнере на Rusonyx VDS за traefik. Приложение parity-подтверждено (ре-ревью №2 PASS: HTML+визуал byte-parity с боем `www.labtools.ru`, ассеты из MinIO, ноль локальных хаков, `@snollajs/snolla@0.28.2`).
|
||||
## 🟢 [labtools-web-vds-deploy] — Деплой `labtools.ru` snolla-приложения (`victor/labtools.ru/apps/web`) в docker-контейнере на Rusonyx VDS за traefik. Приложение parity-подтверждено (ре-ревью №2 PASS: HTML+визуал byte-parity с боем `www.labtools.ru`, ассеты из MinIO, ноль локальных хаков, `@snollajs/snolla@0.28.2`).
|
||||
|
||||
## Кто/где собирает образ (решение workshop)
|
||||
**Образ собирает АДМИН на VDS** из `Dockerfile`, который пишет имплементер. build нужен docker + доступ к verdaccio (`verdaccio.kzntsv.site`) + `VERDACCIO_TOKEN` — эта инфра у админа/на VDS; имплементер владеет корректностью Dockerfile, не реестром. Кросс-машинный трансфер образа не нужен.
|
||||
@@ -1019,9 +1019,9 @@ deps подняты: `@snollajs/snolla ^0.18`, `content-api ^0.13`, `content-api
|
||||
**notify:** OpeItcLoc03/workshop
|
||||
Dev-source: `victor/labtools.ru/apps/web` (parity-док/буфер — в `.workshop/.brainstorm/snolla-sites-migration.md`). Blast: cutover затронет живой прод labtools.ru — staging-first, cutover gated.
|
||||
|
||||
**Status:** in_progress
|
||||
**Where I stopped:** STAGING ЗЕЛЁНЫЙ (2026-07-01). Образ `registry.kzntsv.site/labtools:43e28ba` собран на VDS + push; Portainer stack `labtools` (Id 17) на `labtools.vds.kzntsv.site`, контейнер healthy (MSSQL+S3 подключены); 8 секрет-env в stack-env. Smoke parity vs бой GREEN: все страницы меню 200/200, редиректы `.php`/trailing-slash/lowercase 301 1:1, `theme.css` из MinIO байт-в-байт (Cache-Control 86400), `/assets/*.webp` байт-в-байт. Рунбук: `.wiki/concepts/labtools-vds-deploy-runbook.md`.
|
||||
**Next action:** Cutover live DNS `labtools.ru` — GATED, ждём добро оператора (бой на RUVDS 80.64.31.36 живой, НЕ выводить). По go: добавить `Host(labtools.ru)||Host(www.labtools.ru)` в traefik-rule стека → оператор флипает A-записи reg.ru → 89.253.255.94 → LE cert → smoke на боевом хосте. labtools.pro — ОТДЕЛЬНАЯ таска (deferred, решение оператора 2026-07-01), не в scope.
|
||||
**Status:** 🟢 CLOSED 2026-07-02 — cutover LIVE. `labtools.ru`+`www` на VDS (89.253.255.94), стек 17, образ `labtools:43e28ba`. Рунбук § Cutover обновлён.
|
||||
**Closure:** DNS зона на **Yandex DNS** (не reg.ru). Флип шёл неравномерно — dns1/dns2 расходились; cutover-гейт = ОБА авторитетных Yandex-NS согласованно → VDS по apex+www (монитор дождался). Стек 17 traefik-rule → `Host(labtools.ru)||Host(www.labtools.ru)` (Portainer PUT, env 8/8, pullImage=false); LE-cert выпущен (~t+20s). Live-smoke GREEN: оба хоста 200 (nav+каталог-секции+продукты), редиректы (`/about/` trailing, `/Contacts` lowercase, `/index.php`→`/`) parity, sitemap index (host=labtools.ru non-www — siteUrl тенанта без www), theme-ассеты byte-identical (RUVDS 301 apex→www → прямой md5 артефакт, с -L MD5-OK). staging-host убран (→404). Внешне: apex→VDS 200; www ещё split-brain на кэше RUVDS (200, идентичный контент, тухнет по TTL 6ч). RUVDS = rollback, не тронут. Репорт workshop отправлен. **Весь тираж закрыт: labtools.ru + labtools.pro LIVE на VDS.**
|
||||
**Next action:** — (закрыто). Опционально позже по решению оператора: снять RUVDS-биндинги labtools.ru/www (как для emspb) — сейчас оставлены как rollback.
|
||||
**Branch:** master
|
||||
**Notify:** OpeItcLoc03/workshop
|
||||
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-07-01T13:02:23.634Z -->
|
||||
@@ -1069,7 +1069,7 @@ Dev-source: `victor/labtools.ru/apps/web` (parity-док/буфер — в `.wor
|
||||
|
||||
---
|
||||
|
||||
## ⚪ [labtools-pro-web-vds-deploy] — Вынести `victor/labtools.pro` (snolla-app, `@snollajs/snolla@0.28.7`, server-side Liquid, БД-контент + MinIO-ассеты) с RUVDS IIS в docker-контейнер на VDS kzntsv (89.253.255.94) за traefik. **Зеркало `[emspb-web-vds-deploy]`** — тот же паттерн; рунбуки `emspb-vds-deploy-runbook` / `labtools-vds-deploy-runbook` (.admin вика) читать как шаблон. Код-DONE: ре-ревью PASS (все 9 дименшнов, ноль хаков), независимый ревьюер на живой БД+MinIO.
|
||||
## 🟢 [labtools-pro-web-vds-deploy] — Вынести `victor/labtools.pro` (snolla-app, `@snollajs/snolla@0.28.7`, server-side Liquid, БД-контент + MinIO-ассеты) с RUVDS IIS в docker-контейнер на VDS kzntsv (89.253.255.94) за traefik. **Зеркало `[emspb-web-vds-deploy]`** — тот же паттерн; рунбуки `emspb-vds-deploy-runbook` / `labtools-vds-deploy-runbook` (.admin вика) читать как шаблон. Код-DONE: ре-ревью PASS (все 9 дименшнов, ноль хаков), независимый ревьюер на живой БД+MinIO.
|
||||
|
||||
**Weight:** needs-human
|
||||
**Notify:** OpeItcLoc03/workshop
|
||||
@@ -1103,9 +1103,10 @@ Acceptance = внешний smoke на задеплоенном URL:
|
||||
## Скилы / отчёт
|
||||
invoke `using-vds-ops`/`using-tasks`/`project-discipline`. Написать рунбук `labtools.pro-vds-deploy-runbook` в .admin вике (зеркало emspb). Репорт → OpeItcLoc03/workshop. Ops-acceptance = staging smoke-parity green; cutover — отдельным словом оператора.
|
||||
|
||||
**Status:** ready
|
||||
**Where I stopped:** (not started)
|
||||
**Next action:** Собрать образ registry.kzntsv.site/labtools-pro:7bd9fae на VDS из чистого git-archive 7bd9fae (guard: default.json absent); создать Portainer stack labtools-pro (env verbatim из labtools stack 17) на labtools-pro.vds.kzntsv.site за traefik+LE; staging smoke-parity vs www.labtools.pro (каталог+редиректы+theme-md5+cache=none+sitemap www); репорт workshop. Cutover live DNS — отдельным gated-словом оператора.
|
||||
**Status:** 🟢 CLOSED 2026-07-02 — cutover LIVE. `labtools.pro`+`www` на VDS (89.253.255.94), стек 19, образ `labtools-pro:7bd9fae`. Runbook: `.wiki/concepts/labtools.pro-vds-deploy-runbook.md`.
|
||||
**Closure:** DNS флип подтверждён авторитетным `ns1.reg.ru` (Resolve-DnsName) + 8.8.8.8 → 89.253.255.94 (именно `.pro`; ранние проверки ловили старый TTL-кэш). Стек 19 traefik-rule → `Host(labtools.pro)||Host(www.labtools.pro)` (Portainer PUT, env 8/8 сохранён, pullImage=false); LE-cert выпущен мгновенно (ssl_verify=0). Live-smoke GREEN: оба хоста 200 (nav+каталог+продукты), редиректы parity, sitemap index host=www, контент реальный (lang=en). staging-хост убран (→404). Внешняя проверка с RUVDS-хоста: labtools.pro/www→89.253.255.94 HTTP 200 cert-trusted. RUVDS labtools.pro = rollback, жив, не тронут. Репорт workshop отправлен.
|
||||
**Where I stopped:** Образ `registry.kzntsv.site/labtools-pro:7bd9fae` (+latest, digest `sha256:23d0bc59…`) собран+запушен НА VDS (guard default.json absent OK). Portainer stack `labtools-pro` **Id 19** создан (env verbatim из stack 17, 8 секретов), контейнер healthy, MSSQL+S3 подключены, лог чист. Staging `labtools-pro.vds.kzntsv.site` LE-cert выпущен. **Smoke-parity vs бой `www.labtools.pro` GREEN** (гнал с VDS): статусы nav+3 каталог-секции+продукты 200/200; редиректы (каталог#1→lshm-750, /Contacts→lowercase, /contacts/→trailing) 301 parity; sitemap = index из 7 дочерних, в сумме 25 URL набор==бой, host=www (R3); theme-ассеты 7/7 md5-identical; Cache-Control absent (корректно, `CachingOptions=[]`); контент-страницы реальное тело (delta +155…+222B = host-длина). Косметика (не дефект, отдана workshop): стартовый баннер лога = `labtools.ru (snolla)` (константа из скаффолда). Compose: `host-stacks/vds-kzntsv/labtools-pro.compose.yml`. Репорт workshop отправлен.
|
||||
**Next action:** — (закрыто). Follow-up (не блокер, у workshop): косметика баннера `labtools.ru` в логе (константа app-name из скаффолда). Опционально позже: снять RUVDS-биндинги labtools.pro (как сделано для emspb) — по решению оператора, сейчас оставлены как rollback.
|
||||
**Branch:** master
|
||||
**Notify:** OpeItcLoc03/workshop
|
||||
<!-- created-by: OpeItcLoc03@DESKTOP-NSEF0UK / from: OpeItcLoc03/workshop / 2026-07-02T08:27:39.437Z -->
|
||||
|
||||
@@ -57,12 +57,13 @@ PORT — не переопределять (образ дефолтит 5000; EX
|
||||
- `/assets/<ownerId>/*.webp` из MinIO — **байт-в-байт** с боем (44444, 24354); content-type `application/octet-stream` — как на бою.
|
||||
- Контейнер healthy (MSSQL+S3 подключены).
|
||||
|
||||
## Cutover (live DNS) — GATED, действие ОПЕРАТОРА
|
||||
Бой на [[../entities/ruvds-iis-host]] (`80.64.31.36`) **остаётся живым** до подтверждения. Порядок:
|
||||
1. **(ops)** В стеке `labtools` добавить в traefik-rule: `Host(\`labtools.ru\`) || Host(\`www.labtools.ru\`)` (LE HTTP-01 выпустит cert на первый хит после DNS-flip).
|
||||
2. **(оператор)** reg.ru: A-записи `labtools.ru` + `www.labtools.ru` → `89.253.255.94` (с RUVDS `80.64.31.36`). Понизить TTL заранее.
|
||||
3. Проверить LE cert выпущен + smoke на боевом хосте.
|
||||
4. `labtools.pro` — открытый вопрос (бой IIS обслуживал и его; scope таски = labtools.ru). Решить отдельно.
|
||||
## Cutover (live DNS) — ✅ ВЫПОЛНЕН 2026-07-02
|
||||
⚠️ **DNS зоны `labtools.ru` — на Yandex DNS (`dns1/dns2.yandex.net`), НЕ reg.ru** (в отличие от `labtools.pro`/reg.ru). Порядок был:
|
||||
1. **(оператор)** Yandex DNS: A-записи `labtools.ru` + `www.labtools.ru` → `89.253.255.94` (с RUVDS `80.64.31.36`).
|
||||
2. **(ops) verify перед traefik — критично:** флип шёл неравномерно, **dns1 и dns2 расходились** (dns2 обновился первым, dns1 отставал). Гейт cutover = **ОБА** авторитетных NS согласованно отдают VDS по apex+www (иначе LE мог попасть на dns1→RUVDS→сжечь rate-limit). Публичные резолверы кэшировали до 6ч (TTL 21600) — для LE не критично (резолвит по авторитетному). Cм. memory [operator-dns-flip-verify-domain-before-cutover].
|
||||
3. **(ops) после подтверждения обоих NS:** стек `labtools` (Id 17) traefik-rule → `Host(\`labtools.ru\`) || Host(\`www.labtools.ru\`)` (Portainer PUT, env 8/8 сохранён, pullImage=false). LE-cert выпущен (~t+20s; первые хиты ловили self-signed в окне issuance, потом ssl_verify=0).
|
||||
4. **Live-smoke GREEN:** оба хоста 200 (nav + каталог-секции + продукты); редиректы (`/about/`→trailing, `/Contacts`→lowercase, `/index.php`→`/`) parity; sitemap = index (host=`labtools.ru`, non-www — siteUrl этого тенанта без www, в отличие от .pro/R3); theme-ассеты из MinIO byte-identical бою (RUVDS отдаёт 301 apex→www, поэтому прямой md5 «DIFF» — артефакт; с `-L` MD5-OK). staging-хост `labtools.vds.kzntsv.site` убран (→404). **Внешняя проверка с RUVDS-хоста:** `labtools.ru`→VDS 200; `www` ещё на кэше RUVDS (200, идентичный контент) — split-brain окно, тухнет по TTL.
|
||||
5. `labtools.pro` — **закрыт отдельно** ([[labtools.pro-vds-deploy-runbook]], LIVE 2026-07-02).
|
||||
|
||||
## Rollback
|
||||
- **DNS:** вернуть A-записи `labtools.ru`/`www` → `80.64.31.36` (RUVDS IIS живой, нетронут). Откат = смена DNS.
|
||||
|
||||
78
.wiki/concepts/labtools.pro-vds-deploy-runbook.md
Normal file
78
.wiki/concepts/labtools.pro-vds-deploy-runbook.md
Normal file
@@ -0,0 +1,78 @@
|
||||
---
|
||||
title: labtools.pro snolla-app — VDS deploy runbook (stack / traefik / env / cutover / rollback)
|
||||
type: concept
|
||||
tags: [labtools-pro, labtools, snolla, vds, deploy, docker, portainer, traefik, runbook, migration, catalog]
|
||||
related: [[../entities/vds-kzntsv]], [[../entities/ruvds-iis-host]], [[portainer-stack-management-vds]], [[minio-imgproxy-on-vds]], [[emspb-vds-deploy-runbook]], [[labtools-vds-deploy-runbook]]
|
||||
updated: 2026-07-02
|
||||
---
|
||||
|
||||
# labtools.pro → VDS deploy runbook
|
||||
|
||||
Вынос `labtools.pro` (snolla-приложение, `@snollajs/snolla` **0.28.7**, server-side Liquid, **каталожный сайт**)
|
||||
с [[../entities/ruvds-iis-host]] (catch-all CMS) в отдельный docker-контейнер на [[../entities/vds-kzntsv]]
|
||||
(89.253.255.94), за traefik. Модель — snolla-app: читает БД-контент MoreThenCms (`mssql.kzntsv.site`)
|
||||
+ ассеты из MinIO (`minio.kzntsv.site`) через imgproxy. **Зеркало [[emspb-vds-deploy-runbook]]** — тот же паттерн;
|
||||
отличие: каталог `/products/*` + `Culture=en` (англоязычный близнец labtools.ru) + Cache-Control отсутствует (см. ниже).
|
||||
|
||||
## Артефакты
|
||||
- **Код:** `victor/labtools.pro` @ `7bd9fae` (apps/web, ре-ревью PASS все 9 дименшнов, ноль хаков, snolla 0.28.7 final). `deploy/Dockerfile` (multi-stage node:22-slim, non-root, healthcheck `/robots.txt`).
|
||||
- **Образ:** ⚠️ `registry.kzntsv.site/labtools-pro:7bd9fae` (+`:latest`) — имя **`labtools-pro`**, НЕ `labtools` (тот у labtools.ru!). Собран НА VDS (обход traefik-499). digest `sha256:23d0bc597c8930a1bf443c418a4af68d63b692903963c0e1f9f25baa4a1dd236`.
|
||||
- **Стек Portainer:** `labtools-pro` (**Id 19**, endpoint 1). Source-of-truth compose: `admin/host-stacks/vds-kzntsv/labtools-pro.compose.yml`.
|
||||
- **siteId:** `663F9410-A6CC-4651-9A5C-62844A313957`, activeTheme `389AD745-E3EE-4F23-BE16-DF38440A0941` (theme store MinIO `themes/389ad745e3ee4f23be16df38440a0941/`). Non-secret — в `production.json`, НЕ env.
|
||||
- **siteUrl:** `https://www.labtools.pro` — в `production.json` (R3: sitemap/robots/canonical отдают www).
|
||||
|
||||
## Сборка образа (на VDS)
|
||||
```bash
|
||||
git -C ~/projects/labtools.pro archive --format=tar 7bd9fae \
|
||||
| ssh vitya@89.253.255.94 'rm -rf ~/build/labtools-pro && mkdir -p ~/build/labtools-pro && tar -x -C ~/build/labtools-pro'
|
||||
ssh vitya@89.253.255.94 "cd ~/build/labtools-pro && VERDACCIO_TOKEN='<token>' docker build -f deploy/Dockerfile \
|
||||
--build-arg VERDACCIO_TOKEN -t registry.kzntsv.site/labtools-pro:7bd9fae -t registry.kzntsv.site/labtools-pro:latest . \
|
||||
&& docker push registry.kzntsv.site/labtools-pro:7bd9fae && docker push registry.kzntsv.site/labtools-pro:latest"
|
||||
```
|
||||
- VERDACCIO_TOKEN — `pass vds-kzntsv/full-env VERDACCIO_CI_TOKEN`, build-time only (не в финальный образ; docker linter warn-only).
|
||||
- `config/default.json` (dev-секреты) исключён `.dockerignore` — guard проверен на архиве: default.json ABSENT (только production.json + custom-environment-variables.json + default.example.json).
|
||||
|
||||
## Runtime env-контракт (8 секретов — Portainer stack-env, НЕ в образ/git)
|
||||
**Значения идентичны labtools/emspb** (все snolla-тенанты = одна MoreThenCms + общий MinIO/imgproxy/smtp; tenant-разница = siteId, не секрет). При создании стека env-массив **переиспользован verbatim из labtools stack (Id 17)** через Portainer API. 8 env: `DB_USER DB_PASSWORD IMGPROXY_KEY IMGPROXY_SALT S3_ACCESS_KEY_ID S3_SECRET_ACCESS_KEY SMTP_USER SMTP_PASSWORD`. Маппинг env→config: `apps/web/config/custom-environment-variables.json`.
|
||||
PORT — не переопределять (образ 5000; EXPOSE 5000; healthcheck `/robots.txt`). traefik service-port = 5000.
|
||||
|
||||
## Создание стека (Portainer API, X-API-Key)
|
||||
```bash
|
||||
K=$(pass show vds-kzntsv/full-env | sed -n 's/^PORTAINER_API_KEY=//p'); BASE=https://portainer.vds.kzntsv.site
|
||||
ENV=$(curl -ksS -H "X-API-Key: $K" $BASE/api/stacks/17 | jq '.Env') # verbatim из labtools stack 17
|
||||
COMPOSE=$(cat ~/build/labtools-pro.compose.yml)
|
||||
PAYLOAD=$(jq -n --arg name labtools-pro --arg compose "$COMPOSE" --argjson env "$ENV" '{name:$name,stackFileContent:$compose,env:$env,fromAppTemplate:false}')
|
||||
curl -ksS -X POST "$BASE/api/stacks/create/standalone/string?endpointId=1" -H "X-API-Key: $K" -H 'Content-Type: application/json' --data "$PAYLOAD" # → Id 19
|
||||
```
|
||||
Предусловие pull: `registry.kzntsv.site` зарегистрирован в Portainer как Custom registry Id 1 (иначе `no basic auth`).
|
||||
|
||||
## Runtime egress
|
||||
`mssql.kzntsv.site:1433` (БД-контент) · `minio.kzntsv.site:443` (ассеты) · `imgproxy.kzntsv.site:443` · `smtp.yandex.ru:465` (формы).
|
||||
|
||||
## Staging smoke (2026-07-02, GREEN) — `labtools-pro.vds.kzntsv.site` vs бой `www.labtools.pro` (RUVDS IIS 80.64.31.36)
|
||||
Гнать с самого VDS (воркстейшн ловит LAN-DNS-перехват на `*.labtools.pro`; с VDS бой резолвится публично → RUVDS).
|
||||
- **Status-паритет:** nav (`/ /about /contacts`) + 3 каталог-секции (`/products/laboratory-presses`, `/products/press-forms`, `/products/milling-accessories`) + продукты (`plg-20`, `press-forms/ring`) — все 200/200.
|
||||
- **Редиректы (301 parity, target идентичен modulo host):** каталог#1 `/products/laboratory-ball-mills`→`…/laboratory-ball-mills/lshm-750`; `/Contacts`→lowercase `/contacts`; `/contacts/`→trailing `/contacts`.
|
||||
- **Sitemap — структура index (snolla) vs плоский (legacy), покрытие идентично:** бой отдаёт плоский `/sitemap.xml` с 25 URL; snolla отдаёт **sitemap-INDEX** из 7 дочерних (`sitemap-pages-1` 3, `sitemap-static-pages-1` 2, `sitemap-sections-1` 3, 4× `sitemap-catalog-<GUID>-products-1` = 1+2+2+12=17), все 200, **в сумме ровно 25 URL, набор == бой** (comm — ноль расхождений). `<loc>` host = `www.labtools.pro` (R3). **НЕ дефект** — index-структура штатна для snolla (как pilonuxt).
|
||||
- **theme-ассеты из MinIO md5-IDENTICAL бою** (проверены css/js/png/svg под `/themes/389ad745e3ee4f23be16df38440a0941/`): 7/7 MD5-OK, http 200.
|
||||
- ⚠️ **Cache-Control ОТСУТСТВУЕТ на theme-ассетах — КОРРЕКТНО** (labtools.pro `CachingOptions=[]` empty-config; движок 0.28.7 не ставит заголовок = бой). НЕ флагать как дефект (в отличие от emspb/labtools где был `max-age=86400`).
|
||||
- **Контент-страницы рендерят реальное тело** (12–22 KB), дельта vs бой +155…+222 B — стабильна, объясняется длиной staging-host в canonical/og (на 11 симв. длиннее www; на cutover уравняется в byte-parity).
|
||||
- Контейнер healthy, MSSQL (tedious) + S3 (aws-sdk) подключены, `listening at http://localhost:5000`, лог чист (только deprecation-warnings tedious/aws-sdk-v2).
|
||||
|
||||
### Косметика (не дефект, отдано workshop)
|
||||
Стартовый баннер в логе — `labtools.ru (snolla) listening…` — строка-константа унаследована из labtools.ru-референса при скаффолде. Идентификация сайта = siteId в production.json (663F9410…), на рендер/контент не влияет.
|
||||
|
||||
## Cutover (live DNS) — ✅ ВЫПОЛНЕН 2026-07-02
|
||||
Порядок был (как emspb):
|
||||
1. **(оператор)** reg.ru: A-записи `labtools.pro` + `www.labtools.pro` → `89.253.255.94` (с RUVDS `80.64.31.36`).
|
||||
2. **(ops) verify флипа перед traefik:** предыдущие проверки ловили старый TTL-кэш (публичные резолверы отдавали 80.64.31.36); **авторитетный `ns1.reg.ru` через `Resolve-DnsName` подтвердил** `labtools.pro`+`www` → `89.253.255.94` (TTL 3600), 8.8.8.8 догнал. Именно `.pro` (НЕ `.ru`). Урок: при "поменял DNS" проверять авторитетный NS напрямую, а не только кэширующие резолверы. Cм. memory [operator-dns-flip-verify-domain-before-cutover].
|
||||
3. **(ops) ТОЛЬКО ПОСЛЕ flip:** стек `labtools-pro` (Id 19) traefik-rule → `Host(\`labtools.pro\`) || Host(\`www.labtools.pro\`)` (Portainer PUT, env сохранён 8/8, pullImage=false). LE HTTP-01 выпустил cert **мгновенно** (ssl_verify=0 с первого хита).
|
||||
4. **Live-smoke GREEN:** оба хоста 200 (nav+каталог+продукты); редиректы (ball-mills→lshm-750, /Contacts→lowercase, /contacts/→trailing) parity; sitemap index 7 детей host=www; контент реальный (12728 B, `lang="en"`). staging-хост `labtools-pro.vds.kzntsv.site` убран из rule (→ 404). **Внешняя проверка с RUVDS-хоста (Королёв, public DNS):** `labtools.pro`+`www` → 89.253.255.94 HTTP 200, cert доверенный.
|
||||
5. RUVDS labtools.pro — rollback-путь, жив (отвечает 301, TLS ок), НЕ тронут.
|
||||
|
||||
⚠️ **Порядок критичен:** Host-правило добавлять ТОЛЬКО ПОСЛЕ flip DNS (иначе traefik проактивно тянет LE-cert HTTP-01, challenge упадёт на RUVDS → сожжём rate-limit).
|
||||
|
||||
## Rollback
|
||||
- **DNS:** вернуть A-записи `labtools.pro`/`www` → `80.64.31.36` (RUVDS IIS живой, нетронут). Откат = смена DNS.
|
||||
- **Стек:** Portainer → stack `labtools-pro` (Id 19) → remove (или откат тега образа). Образ в registry остаётся.
|
||||
- RUVDS IIS labtools.pro **не выводить** до явного решения оператора (директива 2026-07-01). (Ср.: emspb.ru биндинги на RUVDS сняты 2026-07-02 после подтверждённого cutover — см. [[../entities/ruvds-iis-host]].)
|
||||
@@ -39,8 +39,8 @@ updated: 2026-06-11
|
||||
|---|---|---|---|
|
||||
| `snolla` (AppPool `snolla`, .NET v4.0 Integrated, ApplicationPoolIdentity) | `C:\sites\snolla\` (8.66 GB / 44725 files, copied 2026-05-23 via SSH/scp) | `*:80:` catch-all HTTP + 25× `*:443:<hostname>` HTTPS SNI | catch-all для всех CMS hostnames через multi-tenant routing в самом CMS |
|
||||
|
||||
**25 HTTPS hostnames bound via SNI** (LE certs imported from traefik `acme.json`, valid до 2026-07-22, R13):
|
||||
- ✅ `emspb.ru` / `www.emspb.ru` — DNS flipped 2026-05-24 ~12:00
|
||||
**HTTPS hostnames bound via SNI** (было 25; сейчас **23** после декоммишна emspb.ru/www — 2026-07-02. `Get-WebBinding` total: 26→24 включая `*:80:` catch-all). LE certs теперь через [[../concepts/winacme-iis-owin-catchall-http01]] (binding-driven `--source iis`, cert до 2026-09-03):
|
||||
- 🗑️ `emspb.ru` / `www.emspb.ru` — **декоммишн 2026-07-02**: миграция на [[../entities/vds-kzntsv]] подтверждена оператором (off-LAN проверка с IIS-хоста: оба → 89.253.255.94 HTTP 200), SNI-биндинги сняты. Backup конфига `pre-emspb-decommission-2026-07-02`. `emspb.snolla.com` **оставлен** (НЕ мигрирован, DNS всё ещё → IIS). Rollback = re-add 2 биндингов (cert в store) или `Restore-WebConfiguration`.
|
||||
- ✅ `kupimknigi.spb.ru` — DNS flipped 2026-05-24 ~00:00 (pilot)
|
||||
- ⏳ 22 more in queue (`pilorama98.ru`/www, `labtools.ru`/www, `labtools.pro`/www, 12× `*.snolla.com`, `rimiz.ru`/www, `maljarka.tandemmebel.ru`, etc.) — pending DNS TTL drop в reg.ru (TTL=86400 пока)
|
||||
- ⛔ `tandemmebel.ru` / `www.tandemmebel.ru` — scope-narrowed 2026-05-24, остаются на windows-IIS на неопределённый срок
|
||||
|
||||
59
host-stacks/vds-kzntsv/labtools-pro.compose.yml
Normal file
59
host-stacks/vds-kzntsv/labtools-pro.compose.yml
Normal file
@@ -0,0 +1,59 @@
|
||||
# labtools-pro — прод-фронт labtools.pro (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).
|
||||
#
|
||||
# Модель: НЕ pilonuxt/Nuxt-contentApi. Это монолит @snollajs/snolla (0.28.7) — читает БД-контент
|
||||
# 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. КАТАЛОЖНЫЙ сайт (secции /products/*, редиректы).
|
||||
#
|
||||
# Образ собирается АДМИНОМ на VDS из victor/labtools.pro/deploy/Dockerfile (build-arg VERDACCIO_TOKEN,
|
||||
# @snollajs/* из verdaccio.kzntsv.site). Тег = git-sha монорепы labtools.pro.
|
||||
# ⚠️ Имя образа labtools-pro (НЕ labtools — тот у labtools.ru).
|
||||
#
|
||||
# Домен: STAGING — labtools-pro.vds.kzntsv.site (под wildcard *.vds.kzntsv.site, cert LE HTTP-01 авто).
|
||||
# Cutover live labtools.pro/www.labtools.pro — ОТДЕЛЬНЫЙ gated шаг: бой живой на RUVDS IIS, НЕ выводить.
|
||||
# DNS переключает ОПЕРАТОР. ⚠️ НЕ путать с labtools.ru — тот флипается отдельно. План отката = revert DNS.
|
||||
#
|
||||
# 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=663F9410-A6CC-4651-9A5C-62844A313957 — non-secret, в production.json (не env).
|
||||
|
||||
services:
|
||||
labtools-pro:
|
||||
container_name: labtools-pro
|
||||
image: registry.kzntsv.site/labtools-pro:7bd9fae # git-sha victor/labtools.pro 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.labtools-pro.entrypoints: websecure
|
||||
# CUTOVER 2026-07-02: DNS labtools.pro/www флипнут на VDS (89.253.255.94) оператором.
|
||||
# Проверено авторитетным ns1.reg.ru + 8.8.8.8 → 89.253.255.94 (НЕ labtools.ru!). Боевые хосты.
|
||||
# staging-хост labtools-pro.vds.kzntsv.site УБРАН post-cutover. RUVDS IIS 80.64.31.36 — rollback, не тронут.
|
||||
traefik.http.routers.labtools-pro.rule: Host(`labtools.pro`) || Host(`www.labtools.pro`)
|
||||
traefik.http.routers.labtools-pro.tls.certresolver: letsEncrypt
|
||||
traefik.http.services.labtools-pro.loadbalancer.server.port: "5000"
|
||||
|
||||
networks:
|
||||
proxy:
|
||||
external: true
|
||||
@@ -44,8 +44,10 @@ services:
|
||||
labels:
|
||||
traefik.enable: "true"
|
||||
traefik.http.routers.labtools.entrypoints: websecure
|
||||
# STAGING-хост. Боевой www.labtools.ru || labtools.ru добавить ТОЛЬКО на cutover-шаге.
|
||||
traefik.http.routers.labtools.rule: Host(`labtools.vds.kzntsv.site`)
|
||||
# CUTOVER 2026-07-02: DNS labtools.ru/www флипнут на VDS (89.253.255.94) оператором (Yandex DNS).
|
||||
# Проверено ОБА авторитетных Yandex-NS (dns1+dns2) согласованно → 89.253.255.94 (НЕ labtools.pro!). Боевые хосты.
|
||||
# staging-хост labtools.vds.kzntsv.site УБРАН post-cutover. RUVDS IIS 80.64.31.36 — rollback, не тронут.
|
||||
traefik.http.routers.labtools.rule: Host(`labtools.ru`) || Host(`www.labtools.ru`)
|
||||
traefik.http.routers.labtools.tls.certresolver: letsEncrypt
|
||||
traefik.http.services.labtools.loadbalancer.server.port: "5000"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user