12 KiB
title, type, tags, sources, updated
| title | type | tags | sources | updated | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Recovery architecture — текущая инфраструктура (2026-05-19, attempt 2) | concept |
|
|
2026-05-19 |
Recovery Architecture Snapshot
Снимок production-инфраструктуры на конец второй (успешной) попытки миграции 2026-05-19. 14 cms hostnames теперь идут через native IIS на windows-recovery-host напрямую. VM snolla-recovery — parallel-fallback, running но больше не на prod-пути (24h+ soak, потом savestate). 2 stayer routes окончательно disabled через traefik (host IIS sites живут для прямого доступа).
История: attempt 1 в этот же день сломал prod, был revert; recipe — в iis-migration-2026-05-19-postmortem. Attempt 2 выполнен по recipe — см. iis-host-migration-2026-05-19 Phase 10.
Это рабочее, но всё ещё временное состояние — single-point-of-failure на бытовом железе. Замечания по улучшению — future-resilient-architecture-goals.
Цепочка запроса от клиента до CMS (host-IIS chain, attempt 2)
Клиент (browser)
→ DNS resolve (REGRU): *.snolla.com (включая on.snolla.com — default subdomain),
labtools.ru/pro, pilorama98.ru, tandemmebel.ru, emspb.ru, kupimknigi.spb.ru,
maljarka.tandemmebel.ru, sestech.ru, ics-artmaterials.com, rimiz.ru (404 CMS-side)
→ 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:8089/
→ host:8089 → IIS site `snolla` (binding *:8089)
→ IIS native на хосте
→ site `snolla`, .NET Framework 4.8.1, AppPoolIdentity
→ C:\sites\snolla\, sitePath patched, conn → localhost
→ ASP.NET CMS code (.NET Framework 4.8)
→ Connection strings:
→ MSSQL: Data Source=localhost,1433 (host:1433 = MSSQL container)
→ MinIO/storage: вопрос снят пользователем
→ Elasticsearch: не используется CMS
→ MSSQL container на host:1433
→ 5 production DB (MoreThenCms, Stayer*, stostayer, TireService)
← HTTP response back through chain
VM snolla-recovery: running parallel, no traffic (24h+ soak fallback). NAT port forwards :18080/:18180/:18181/:18189 холостые. Будет savestate'ena после стабильности → потом unregistervm для освобождения ~92 GB.
Stayer chain — DISABLED через traefik
stostayer.snolla.com / old.stostayer.ru
→ DNS → 94.19.247.14
→ router → traefik
→ match Host → нет routes (stostayer.yml.disabled, oldstostayer.yml.disabled)
→ traefik 404 "no route"
Host IIS sites stostayer (:8090) и stostayer.old (:8091) живут для прямого/локального доступа. Conn-strings:
stostayer:Data Source=www.stostayer.ru,1433, userstayer_site, password XML-escaped см. webconfig-password-xml-escapestostayer.old:Data Source=localhost(наш MSSQL контейнер)
Запущенные 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 routes (после attempt 2)
11 cms yml репойнтены на host IIS:8089. 2 stayer yml — .disabled.
| File | Hosts | Backend | Статус |
|---|---|---|---|
| snolla.yml | snolla.com + 10 *.snolla.com subdomains (rule explicit) | host.docker.internal:8089 | active → host IIS |
| rimiz.yml | rimiz.ru, www.rimiz.ru | host.docker.internal:8089 | active (но CMS-side 404 — known) |
| labtools.yml | labtools.ru, www.labtools.ru | host.docker.internal:8089 | active → host IIS |
| labtoolspro.yml | labtools.pro, www.labtools.pro | host.docker.internal:8089 | active → host IIS |
| pilorama98.yml | pilorama98.ru, www.pilorama98.ru | host.docker.internal:8089 | active → host IIS |
| tandemmebel.yml | tandemmebel.ru, www.tandemmebel.ru | host.docker.internal:8089 | active → host IIS |
| emspb.yml | emspb.ru, www.emspb.ru | host.docker.internal:8089 | active → host IIS (canary 1, phone-test ✅) |
| kupimknigi.yml | kupimknigi.spb.ru | host.docker.internal:8089 | active → host IIS |
| maljarka.yml | maljarka.tandemmebel.ru | host.docker.internal:8089 | active → host IIS |
| sestech.yml | sestech.ru, www.sestech.ru | host.docker.internal:8089 | active → host IIS |
| isc-artmaterials.yml | ics-artmaterials.com, www.ics-artmaterials.com | host.docker.internal:8089 | active → host IIS (CMS-side 404 — known) |
| stostayer.yml.disabled | stostayer.snolla.com | (n/a, route disabled) | DISABLED, host IIS :8090 локально |
| oldstostayer.yml.disabled | old.stostayer.ru | (n/a, route disabled) | DISABLED, host IIS :8091 локально |
Backup-stamp файлы (накопились за обе попытки):
*.yml.bak-2026-05-19— самый ранний backup (до session).*.yml.bak-phase3-2026-05-19— rollback baseline (attempt 1 → revert state, всё на VM:18080).*.yml.bak-hostip-2026-05-19— failed attempt 1 (host.docker.internal:80 ⇒ Docker NAT loop).*.yml.bak-stayer-switch-2026-05-19— stayer switch attempt artefact (Phase 5/6 prev session).*.yml.bak-pre-attempt2-2026-05-19— текущая live conf attempt 2 (host:8089 backend). Это baseline для atomic revert этой попытки.
Плюс 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 мёртвой синки)
Host IIS configuration (active prod)
| Site | Bindings | Physical path | Pool identity | Прим. |
|---|---|---|---|---|
| snolla | *:80, *:8089 |
C:\sites\snolla |
ApplicationPoolIdentity (.NET v4.0 Integrated) |
active prod — catch-all для 11 cms hosts, traefik backend :8089 |
| stostayer | *:8090 |
C:\sites\stostayer |
ApplicationPoolIdentity |
local-only (traefik route disabled), conn → www.stostayer.ru,1433 |
| stostayer.old | *:8091 |
C:\sites\stostayer.old |
ApplicationPoolIdentity |
local-only (traefik route disabled), conn → localhost,1433 |
| Default Web Site | (stopped, autoStart=false) | — | — | — |
ACL: IIS AppPool\<site>:(OI)(CI)M рекурсивно на каждом site root.
DNS
Все домены остались указывать на 94.19.247.14 (public IP, статический). REGRU как registrar/DNS.
Backup инфраструктура
Текущая (на момент 2026-05-19, после attempt 2):
- kreknin-synology держит Hyper Backup репо мёртвой синки (~430 GB). Новых бэкапов с recovered Windows-PC НЕТ.
- Локально на Windows-PC:
C:\nas-recovery\vm-sites\(~11 GB, дамп IIS sites из VM до patches) — резерв если host-IIS сломается катастрофически. После 48h+ uptime можно почистить. C:\nas-recovery\backup\snolla\snolla.ova(42.5 GB) — оригинал OVA. После cleanup 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-страницы.
Известные открытые баги
X-Forwarded headers не передаются от traefik в IIS → CMS делает redirect с→ RESOLVED 2026-05-19 вечер через URL Rewrite 2.1 +:4443в URL.<serverVariables>rule на host IIS. Также закрыл утечку:8089в admin SPA после attempt 2 миграции. См. cms-server-port-leak-fix.- rimiz.ru → 404. CMS-side, не инфра.
- ics-artmaterials.com → 404. Аналогично — CMS-side (
www.ics-artmaterials.com → 301 → ics-artmaterials.com → 404). emspb.snolla.com→ RESOLVED 2026-05-19 вечер через DB seed root AssetsFolder rows для 15 sites без них (включая emspb, pilorama98, и др.). Симптом был НЕ site-specific — общий для всех sites которые никогда не использовали admin assets UI. См. cms-admin-assets-root-folder-seed. Долгосрочный TODO — null-guard в/admin/assets/<guid>/getList→ 500 NullReferenceException.AssetsJsonViewModelBuilder.Build(требует recompile DLL, отложено до восстановления build env).- acme.json HTTP-01 renewal будет фейлить для доменов с DNS не на нашем IP → переезд на DNS-01 через REGRU до истечения сертификатов (~3 месяца).
- *C:\inetpub\logs* растёт — нужна ротация.
- docker.sock provider в traefik не работает — но не блокирует (всё через file-provider). См. traefik-on-windows-docker-desktop Pitfall 3.
- WinHTTP proxy на хосте strips response headers для
curl.exe http://localhost:...— для loop-detect/IIS confirmation использоватьdocker exec traefik wgetилиInvoke-WebRequest. См. docker-host-loopback-detect.
Single Points of Failure
- Один Windows-PC (если сгорит — всё ляжет)
- Один публичный IP / провайдер
- Один WiFi-канал
- Один OpenWRT-роутер
- Один host IIS instance обслуживает весь cms-трафик (VM остаётся parallel fallback ещё 24-48h)
- Один MSSQL контейнер (single primary, нет replica)
- Один MinIO (single drive, не distributed)
Каждый SPOF — кандидат на улучшение в future-resilient-architecture-goals.