docs(.wiki): ingest iis-host-migration attempt 2 (success) + docker-host-loopback-detect
Phase 10 успех — recipe из post-mortem применён полностью: backend port :8089, bak-pre-attempt2 серия, IIS binding + Stop+Start, loop-detect через docker exec wget, 2 canary phone-tests от мобильного интернета, batch 9 cms; stayer routes user-ом подтверждены internal → .yml.disabled. Touched: - sources/iis-host-migration-2026-05-19.md — append Phase 10 - concepts/iis-migration-2026-05-19-postmortem.md — footer attempt-2-succeeded с маппингом recipe A-G - concepts/recovery-architecture-snapshot.md — major rewrite, chain через host-IIS:8089, VM = parallel fallback - entities/snolla-recovery-vm.md — status parallel-fallback, 24-48h soak - entities/windows-recovery-host.md — IIS sites active prod - NEW concepts/docker-host-loopback-detect.md — recipe loop-detect + WinHTTP-proxy gotcha - index.md, log.md
This commit is contained in:
@@ -176,3 +176,66 @@ Production снова на VM-chain (как было в начале сесси
|
||||
- Web.config'и в `C:\sites\` пропатчены правильно (sitePath, conn-strings, stostayer на новый DB) — можно переиспользовать.
|
||||
- IIS sites/pools уже настроены — переключение требует только traefik backend patch + tested correctly.
|
||||
- Recipe для правильной миграции — в [[iis-migration-2026-05-19-postmortem]].
|
||||
|
||||
---
|
||||
|
||||
## Phase 10 — Attempt 2 (вечер 2026-05-19, после прочтения post-mortem)
|
||||
|
||||
Повторная попытка миграции, выполненная **по recipe из [[iis-migration-2026-05-19-postmortem]]**. Все 5 главных правил соблюдены, миграция прошла без incidents.
|
||||
|
||||
### Что сделано
|
||||
|
||||
1. **Read-only sanity (без prod-touches):** VM running confirmed, port-scan на хосте показал `:18090` и `:8089` свободны, traefik dir contains 4 серии bak-stamp'ов сохранённых от attempt 1, IIS sites/pools (`snolla, stostayer, stostayer.old`) живы.
|
||||
2. **Backend port: `:8089`** (recipe-A — НЕ `:80`, НЕ совпадает с traefik publish `:8000/:4443/:8080`, НЕ совпадает с VM NAT forwards `:18080/:18180/:18181`). Выбор user'а (был кандидат `:18090`, user предпочёл `:8089`).
|
||||
3. **Atomic revert plan ДО старта** (recipe-E): новая bak-серия `.bak-pre-attempt2-2026-05-19` для всех 13 yml (11 cms + 2 stayer), paste-ready команда восстановления записана в `.tasks/STATUS.md`.
|
||||
4. **IIS binding** `snolla *:8089` добавлен через elevated PS (`New-WebBinding` + `Stop-Website; Start-Website` — recipe-A note: без restart binding не активируется).
|
||||
5. **Loop-detect через `docker exec`** (recipe-A + recipe-F): `docker exec traefik wget --spider -S --header="Host: emspb.ru" http://host.docker.internal:8089/` → first response `301 → http://www.emspb.ru/` от `Server: Microsoft-IIS/10.0`. `host.docker.internal` resolves to `192.168.65.254:8089` — это Docker Desktop host gateway, **не traefik publish-port**. NO NAT loop. См. [[docker-host-loopback-detect]] про общую технику.
|
||||
6. **Smoke test с `-MaximumRedirection 0`** (recipe-B): `curl.exe -k -I --max-redirs 0 -H "Host: emspb.ru" https://localhost:4443/` → first response `301`, `Server: Microsoft-IIS/10.0`, `Location: http://www.emspb.ru/`. Это **expected CMS canonical redirect** (та же логика что была на VM).
|
||||
7. **Canary atomic** — patched ОДИН yml (`emspb.yml`), file-provider auto-reload, public smoke clean → 📱 **phone-test с мобильного интернета** (recipe-C) → `https://emspb.ru/` открылось → ✅.
|
||||
8. **Second canary** — `labtools.yml`, smoke + phone-test → ✅.
|
||||
9. **Batch patch** оставшихся 9 cms yml (snolla, rimiz, labtoolspro, pilorama98, tandemmebel, kupimknigi, maljarka, sestech, isc-artmaterials) одним PS-блоком (recipe-G: batch не item-by-item) → smoke 20 hostnames → все `Server: Microsoft-IIS/10.0` ✅.
|
||||
10. **Stayer routes — disabled** (re-confirmed Phase 7 decision): user подтвердил «stayer'ы локальные, через traefik наружу не светят». Rename `stostayer.yml → stostayer.yml.disabled`, `oldstostayer.yml → oldstostayer.yml.disabled`. `docker restart traefik` (file-provider не подхватил deletion auto-reload). Verify: `stostayer.snolla.com`/`old.stostayer.ru` → `404 text/plain` (traefik no-route). Host IIS sites `:8090`/`:8091` остаются live для прямого/локального доступа.
|
||||
11. **VM running parallel** (recipe-D): VM **НЕ savestate'ить** минимум 24h+. Освободит RAM/disk только после подтверждённой стабильности host'а.
|
||||
|
||||
### Pitfall found and resolved
|
||||
|
||||
- **WinHTTP proxy strips Server header.** Локальный `curl.exe http://localhost:8090/` returned response без `Server: Microsoft-IIS/10.0` и без `X-Powered-By: ASP.NET` (плюс с `Proxy-Connection: keep-alive`) — выглядело как «не IIS отвечает». Это привело к moment'у panic. Но `docker exec traefik wget ...` (real production path) **показал headers корректно**. Вывод: для loop-detect / IIS-confirmation тестов **использовать `docker exec` из traefik container**, не Windows `curl.exe` — последний ходит через Windows-уровневый proxy который headers вырезает.
|
||||
|
||||
### My mistake during this session
|
||||
|
||||
- Я неверно интерпретировал «мигрировать stayer'ов» как «patch traefik backend → host:8090/8091» (т.е. пускать через traefik наружу). User имел в виду «host IIS уже на :8090/:8091, traefik routes должны быть **DISABLED**». Сделал prod-changing patch → user интервент-stop → revert + rename `.yml.disabled`. См. memory `feedback-migrate-semantics`. Lesson — переспрашивать semantics для internal/low-traffic сервисов перед prod-changing.
|
||||
|
||||
### Финальный chain (после attempt 2)
|
||||
|
||||
```
|
||||
Клиент (browser)
|
||||
→ DNS → 94.19.247.14 (public IP)
|
||||
→ OpenWRT NAT 443 → 192.168.1.143:4443
|
||||
→ traefik:4443 (TLS termination)
|
||||
→ match Host → одно из 11 cms-yml → backend
|
||||
→ http://host.docker.internal:8089/
|
||||
↳ Docker Desktop host gateway 192.168.65.254:8089
|
||||
→ Windows host IIS site `snolla` (*:80 + *:8089 bindings)
|
||||
→ C:\sites\snolla\, .NET Framework 4.8.1, ApplicationPoolIdentity
|
||||
→ conn → MSSQL container на host:1433
|
||||
← HTTP response
|
||||
```
|
||||
|
||||
Stayer chain: traefik routes disabled. `stostayer.snolla.com` / `old.stostayer.ru` → traefik 404. Host IIS sites `:8090`/`:8091` живут для локального доступа.
|
||||
|
||||
VM `snolla-recovery`: **running parallel** (24h+ soak), backend в traefik больше не используется — VM NAT port forwards (`:18080/:18180/:18181`) холостые.
|
||||
|
||||
### Артефакты этой сессии
|
||||
|
||||
- `.tasks/STATUS.md` — статус task'а 🔴 active.
|
||||
- traefik backups в `data/custom/`: `*.yml.bak-pre-attempt2-2026-05-19` для 13 yml, плюс `stostayer.yml.disabled`, `oldstostayer.yml.disabled`.
|
||||
- `feedback-migrate-semantics` memory — урок для будущих сессий.
|
||||
- `concepts/docker-host-loopback-detect.md` — новый concept для loop-detect technique.
|
||||
|
||||
## Что осталось open
|
||||
|
||||
- **24h+ soak** до savestate VM (минимум до утра 2026-05-20, лучше 48h до 2026-05-21).
|
||||
- **VM cleanup**: после soak — `savestate` (освободит RAM), позже `unregistervm --delete` (освободит ~92 GB).
|
||||
- **Port forwards OpenWRT** (`host:18080/18180/18181/18189` → VM) — больше не нужны, удалить позже.
|
||||
- **rimiz.ru / ics-artmaterials.com 404** — CMS-side routing issues, не инфра. Открытым.
|
||||
- **X-Forwarded headers** (`:4443` в redirect URL) — известный bug [[traefik-on-windows-docker-desktop]] Pitfall 5, отдельная задача.
|
||||
|
||||
Reference in New Issue
Block a user