Files
admin/recovery-architecture-snapshot.md
vitya 2d307f2dd0 docs(.wiki): iis-migration rollback + post-mortem + xml-escape concept
Phase 9 — rollback миграции на host-IIS из-за Docker port-loop
(host.docker.internal:80 от traefik container резолвится обратно
в сам traefik через NAT, https.yml http-catchall middleware
отдавал 301 -> TOO_MANY_REDIRECTS). Prod снова через VM.

- iis-migration-2026-05-19-postmortem: 10 ошибок миграции +
  recipe для следующей попытки (backend port НЕ :80, smoke с
  MaximumRedirection 0, тест из НЕ-LAN, parallel VM x N часов,
  atomic revert plan)
- webconfig-password-xml-escape: новая gotcha — & в conn-string
  пароле требует & в Web.config (XML reserved char)
- iis-host-migration-2026-05-19: Phase 9 rollback chronology +
  что осталось на хосте inert
- snolla-recovery-vm: статус -> active prod (обратно)
- windows-recovery-host: host IIS sites -> inert artifacts
- recovery-architecture-snapshot: chain снова через VM,
  traefik backends восстановлены из .bak-phase3

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 15:08:07 +03:00

152 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Recovery architecture — текущая инфраструктура (2026-05-19)
type: concept
tags: [architecture, current-state, snapshot, recovery]
sources: [../sources/nas-recovery-session-2026-05-18.md, ../sources/iis-host-migration-2026-05-19.md]
updated: 2026-05-19
---
# Recovery Architecture Snapshot
Снимок production-инфраструктуры на конец 2026-05-19, **после отката миграции** (попытка миграции на host-IIS не удалась — см. [[iis-migration-2026-05-19-postmortem]]). Prod снова через VM `snolla-recovery`, как было до session start. Это **рабочее, но временное** состояние — single-point-of-failure на бытовом железе. Замечания по улучшению — [[future-resilient-architecture-goals]].
## Цепочка запроса от клиента до CMS (после revert 2026-05-19)
```
Клиент (browser)
→ DNS resolve (REGRU): *.kzntsv.site, snolla.com, labtools.pro/ru, pilorama98.ru,
tandemmebel.ru, emspb.ru, kupimknigi.spb.ru, maljarka.tandemmebel.ru,
sestech.ru, ics-artmaterials.com (rimiz.ru — резолвится, но CMS отдаёт 404)
→ 94.19.247.14 (public IP, статический у провайдера)
→ router OpenWRT (192.168.1.1) [[openwrt-router]]
→ NAT 443 → 192.168.1.143:4443
→ NAT 80 → 192.168.1.143:8000
→ Windows-PC (192.168.1.143) [[windows-recovery-host]]
→ traefik 2.6.6 на 4443/8000
→ TLS termination, certResolver=letsEncrypt из acme.json
→ match по Host header (file-provider rules в data/custom/*.yml)
→ backend = http://host.docker.internal:18080/
→ host:18080 = VBox NAT port forward → VM:80
→ snolla-recovery VM [[snolla-recovery-vm]]
→ IIS на :80, site MoreThenCms.Web (catch-all)
→ ASP.NET CMS code (.NET Framework 4.8)
→ Connection strings:
→ MSSQL: Data Source=10.0.2.2:1433 (VBox NAT gateway = host)
→ MinIO/storage: вопрос снят пользователем
→ Elasticsearch: не используется CMS
→ MSSQL container на host:1433
→ 5 production DB (MoreThenCms, Stayer*, stostayer, TireService)
← HTTP response back through chain
```
## Цепочка для stayer'ов (тоже через VM)
```
Клиент → ... → traefik
→ backend = host.docker.internal:18180 (stostayer) или :18181 (stostayer.old)
→ VBox NAT port forward → VM:8080 или VM:8081
→ IIS в [[snolla-recovery-vm]]
→ stostayer: Data Source=89.253.219.2,1433 (НЕ работающий внешний сервер — но stayer'ы и так не отвечают, по словам user'а)
→ stostayer.old subapps (calc/price/tireService) — отдельные pools
```
**Внимание:** stostayer-DB на `89.253.219.2` мёртвая. В host-копии (`C:\sites\stostayer\Web.config`) уже patched на новый `www.stostayer.ru,1433` (user `stayer_site`) с XML-escape `&amp;` в password — но это inert. При следующей попытке миграции — этот патч уже готов.
## На хосте параллельно (inert, не на prod-пути)
См. [[windows-recovery-host]] "Inert" — `C:\sites\{snolla, stostayer, stostayer.old, snolla-identity-manager}` + IIS sites/pools `snolla, stostayer, stostayer.old` готовы к переключению traefik, но не активны.
## Запущенные docker контейнеры на хосте
| Container | Image | Port (host) | Volume |
|---|---|---|---|
| **traefik** | `traefik:v2.6.6` | 4443, 8000, 8080 | named: `traefik_traefik_letsencrypt`; bind: `data/traefik.yml`, `data/custom/` |
| **mssql** | `mcr.microsoft.com/mssql/server:2019-latest` | 1433 | named: `mssql_mssql_data` (filled from production tar) |
| **minio** | `minio/minio:RELEASE.2020-07-13T18-09-56Z` | 9000 | bind: `./data` |
| **imgproxy** | `darthsim/imgproxy:latest` | 8787 | (нет state) |
| **imgproxy-nginx** | `nginx:alpine` | 8788 | bind: `./nginx/cache`, `./nginx/nginx.conf` |
| **elasticsearch** | `elasticsearch:7.10.1` | 9200 | bind: `./data` |
Все на docker network `proxy` (external) — это позволяет traefik резолвить `minio`, `elasticsearch`, `imgproxy-nginx` напрямую по docker DNS.
## Traefik routes (после revert 2026-05-19)
Все активные routes снова указывают на VM (как было до session). Backups сохранены для следующей попытки миграции.
| File | Hosts | Backend | Статус |
|---|---|---|---|
| snolla.yml | snolla.com + 10 subdomains | host.docker.internal:18080 → VM | active |
| rimiz.yml | rimiz.ru, www.rimiz.ru | host.docker.internal:18080 → VM | active (но CMS отдаёт 404 — известное) |
| labtools.yml | labtools.ru, www.labtools.ru | host.docker.internal:18080 → VM | active |
| labtoolspro.yml | labtools.pro, www.labtools.pro | host.docker.internal:18080 → VM | active |
| pilorama98.yml | pilorama98.ru, www.pilorama98.ru | host.docker.internal:18080 → VM | active |
| tandemmebel.yml | tandemmebel.ru, www.tandemmebel.ru | host.docker.internal:18080 → VM | active |
| emspb.yml | emspb.ru, www.emspb.ru | host.docker.internal:18080 → VM | active |
| kupimknigi.yml | kupimknigi.spb.ru | host.docker.internal:18080 → VM | active |
| maljarka.yml | maljarka.tandemmebel.ru | host.docker.internal:18080 → VM | active |
| sestech.yml | sestech.ru, www.sestech.ru | host.docker.internal:18080 → VM | active |
| isc-artmaterials.yml | ics-artmaterials.com, www.ics-artmaterials.com | host.docker.internal:18080 → VM | active |
| stostayer.yml | stostayer.snolla.com | host.docker.internal:18180 → VM:8080 | active |
| oldstostayer.yml | old.stostayer.ru | host.docker.internal:18181 → VM:8081 | active |
**Backup-stamp файлы** (накопились — для следующей попытки):
- `*.yml.bak-phase3-2026-05-19` — original state до Phase 3 (всё указывает на VM). Это **именно та конфигурация что сейчас live** (свежескопировано в active).
- `*.yml.bak-hostip-2026-05-19` — попытка переключения на `host.docker.internal:80` (создала loop, см. [[iis-migration-2026-05-19-postmortem]]).
- `stostayer.yml.bak-stayer-switch-2026-05-19`, `oldstostayer.yml.bak-stayer-switch-2026-05-19` — попытка stayer'ов на host :8090/:8091 (live теперь снова на VM).
Плюс file-provider маршруты для инфраструктурных хостов:
| File | Host | Backend |
|---|---|---|
| elasticsearch.yml | elasticold.kzntsv.site | http://elasticsearch:9200 + basicAuth `books:...` |
| minio.yml | minio.kzntsv.site | http://minio:9000 |
| imgproxy.yml | imgproxy.kzntsv.site | http://imgproxy-nginx:80 |
И мёртвые (не отключены, но смотрят в никуда):
- `disk.yml` → 192.168.1.10:5005 (Synology disk на мёртвой синке)
- `dsm.yml` → 192.168.1.10:5000 (DSM мёртвой синки)
## DNS
Все домены остались указывать на **94.19.247.14** (public IP, статический). REGRU как registrar/DNS. Никаких DNS-изменений во время recovery не требовалось — only router NAT перенастроен.
## Backup инфраструктура
Текущая (на момент 2026-05-19):
- [[kreknin-synology]] держит Hyper Backup репо мёртвой синки (~430 GB). Новых бэкапов с recovered Windows-PC **НЕТ** — рабочее состояние на Windows-PC не бэкапится никуда.
- Локально на Windows-PC: `C:\nas-recovery\vm-sites\` (~11 GB, дамп IIS sites из VM) — резерв если VM полностью умрёт.
**Дыра:** если Windows-PC сгорит — ВСЁ ляжет. Никакой репликации, никакого off-site backup для нового рабочего состояния.
## SSH ключи и доступ
- [[windows-recovery-host]] → [[kreknin-synology]]: `id_ed25519_kreknin` (vitya@195.19.90.188)
- [[windows-recovery-host]] → [[openwrt-router]]: `id_ed25519_openwrt` (root@192.168.1.1)
- [[windows-recovery-host]] → [[snolla-recovery-vm]]: `id_ed25519_snolla_vm` (vitya@127.0.0.1:8022)
После recovery — отозвать публичные ключи Claude из этих 3 машин (`~/.ssh/authorized_keys` или эквивалент). См. соответствующие entity-страницы.
## Известные открытые баги
1. **X-Forwarded headers** не передаются от traefik в IIS → CMS делает редирект с `:4443` в URL. См. [[traefik-on-windows-docker-desktop]] Pitfall 5.
2. **rimiz.ru → 404**. CMS-side, не инфра — mapping host header → CMS-сайт в БД.
3. **acme.json HTTP-01 renewal** будет фейлить для доменов с DNS не на нашем IP — нужен переезд на DNS-01 через REGRU до истечения сертификатов (~3 месяца).
4. **C:\inetpub\logs\** в VM растёт (6+ GB к recovery). На хосте та же беда если когда-то переключимся.
5. **docker.sock provider в traefik** не работает — но не блокирует (всё через file-provider). См. [[traefik-on-windows-docker-desktop]] Pitfall 3.
6. **stostayer DB в VM указывает на мёртвый 89.253.219.2** — stayer'ы публично возможно не работают полноценно (user сказал "стайеры и на VM не работает" — подтвердил). Host-копия уже patched на новый `www.stostayer.ru,1433`, в VM не правили.
7. **MinIO/Azure storage** в CMS — вопрос пользователем снят, оставлено как есть.
8. **VM network adapter "виснет"** периодически (recipe `ipconfig /release /renew` через guestcontrol в [[vbox-windows-stability-tuning]]). Подтверждено ещё раз в сессии 2026-05-19.
## Single Points of Failure
- Один Windows-PC (если сгорит — всё ляжет)
- Один публичный IP / провайдер
- Один WiFi-канал
- Один OpenWRT-роутер
- **Одна VBox VM `snolla-recovery`** — single instance, обслуживает весь CMS-трафик (после revert)
- Один MSSQL контейнер (single primary, нет replica)
- Один MinIO (single drive, не distributed)
Каждый SPOF — кандидат на улучшение в [[future-resilient-architecture-goals]].