git-subtree-dir: .wiki/sources git-subtree-mainline:d25c0577c8git-subtree-split:a5e96432bc
276 lines
27 KiB
Markdown
276 lines
27 KiB
Markdown
---
|
||
title: IIS Host Migration Session 2026-05-19
|
||
type: source
|
||
tags: [migration, iis, windows, recovery, traefik]
|
||
ingested: 2026-05-19
|
||
raw_path: ../../.tasks/iis-on-host-migration.md
|
||
updated: 2026-05-21
|
||
---
|
||
|
||
# IIS Host Migration Session 2026-05-19
|
||
|
||
Перенос основного CMS-сайта (`MoreThenCms.Web`, обслуживает 11 клиентских доменов через Host header) с IIS внутри [[snolla-recovery-vm]] на нативный IIS [[windows-recovery-host]]. Цель — убрать VBox как слой нестабильности.
|
||
|
||
## Хронология
|
||
|
||
**Старт сессии** (после [[nas-recovery-session-2026-05-18]]) — VM один раз отвалилась сетью, оживили через `VBoxManage guestcontrol` + `ipconfig /release /renew` (recipe в [[vbox-windows-stability-tuning]] подтверждён ещё раз).
|
||
|
||
**Phase 1 — discovery (read-only):**
|
||
- В VM через SSH (NAT-forward 127.0.0.1:8022, не bridged 192.168.1.15 — это устарело): `appcmd list site/apppool/app/vdir /xml`.
|
||
- На хосте: `Get-WindowsOptionalFeature -Online IIS-*` через elevated PS — все нужные фичи (`IIS-WebServer`, `IIS-ASPNET45`, `IIS-NetFxExtensibility45`, `IIS-ISAPIFilter`, `IIS-ManagementConsole`, `IIS-IIS6ManagementCompatibility`, `IIS-Metabase`) уже установлены. `WebAdministration` PS-module грузится из admin-PS.
|
||
- В источниках на хосте (`grep`): hardcoded `C:\inetpub\wwwroot\` в коде CMS нет — всё через `ConfigurationManager.AppSettings["sitePath"]`. **НО** в prod Web.config (из backup `vm-sites\`) ключ `sitePath` явно проставлен абсолютным путём — патч в Phase 2 необходим.
|
||
|
||
**Phase 1 находки (важные расхождения с wiki):**
|
||
- `Snolla.IdentityManager` в VM **на :8089, не :80** (вики говорила :80). Sub-apps stostayer.old `/calc`, `/price`, `/price/tireService` существуют с отдельными app pools.
|
||
- `C:\stayer\Snolla.IdentityManager\Web.config` указывает на **`SRV-1135520-1\SQLEXPRESS` + Integrated Security** — мёртвый внешний сервер. Сайт точно не работает, deploy-артефакт без живого консьюмера.
|
||
- `C:\stayer\MoreThenCms.Web\Web.config` (stostayer) использует **внешний production MSSQL `89.253.219.2,1433`** с user `stostayer` — это **другая инфраструктура**, не наш контейнер.
|
||
|
||
**Phase 2 — миграция (admin PS):**
|
||
- `Default Web Site` остановлен (`autoStart=false`).
|
||
- `robocopy` из `C:\nas-recovery\vm-sites\` → `C:\sites\MoreThenCms.Web` (8.7 GB / 44.7k файлов / 1m13s) и → `C:\stayer\` (2.2 GB / 13.9k файлов / 21s).
|
||
- Web.config patch только для `C:\sites\MoreThenCms.Web\Web.config`: `sitePath` `C:\inetpub\wwwroot\MoreThenCms.Web\` → `C:\sites\MoreThenCms.Web\` + `Data Source=10.0.2.2` → `Data Source=localhost`. UTF-8 with BOM через `[System.IO.File]::WriteAllText` (паттерн из [[cms-config-rewrite-pattern]]).
|
||
- 3 AppPool (`.NET v4.0` Integrated, `ApplicationPoolIdentity`): `MoreThenCms.Web`, `stostayer`, `stostayer.old`.
|
||
- 3 IIS-сайта: `MoreThenCms.Web *:80` (catch-all), `stostayer *:8090`, `stostayer.old *:8091`.
|
||
- ACL `icacls /grant 'IIS AppPool\<site>:(OI)(CI)M' /T` на каждый physical root.
|
||
- Skip: `Snolla.IdentityManager` (по решению — публично не нужен), 3 sub-apps stostayer.old (по решению).
|
||
- Smoke test через `http://localhost/` с Host header: все 11 хостов отвечают (большинство 302 redirect — CMS работает). `rimiz.ru` — 404 (CMS-side, не инфра). stostayer/oldstostayer на :8090/:8091 — timeout, **в текущей сессии не разбирались**.
|
||
|
||
**Phase 3 — traefik switch (file-provider auto-reload):**
|
||
- Backup `*.yml.bak-phase3-2026-05-19` для 11 файлов в `C:\Users\vitya\projects\docker\diskstation\traefik\data\custom\`.
|
||
- Patch: `host.docker.internal:18080` → `host.docker.internal:80` (11 yml: snolla, rimiz, labtools, labtoolspro, pilorama98, tandemmebel, emspb, kupimknigi, maljarka, sestech, isc-artmaterials). UTF-8 без BOM.
|
||
- **Не трогали** `stostayer.yml` (`:18180`) и `oldstostayer.yml` (`:18181`) — stayer-сайты остаются на VM.
|
||
- Public smoke через `https://localhost:4443/` с Host header: **10/11 → HTTP 200**. Только `rimiz.ru` → 404 (как и в локальном тесте).
|
||
|
||
## Результат
|
||
|
||
Production-трафик 10 главных доменов теперь идёт **полностью без VM**: client → OpenWRT → traefik → host-IIS native → MSSQL container на хосте. VM продолжает обслуживать только stostayer/oldstostayer через старые NAT port forwards (`:18180/:18181`).
|
||
|
||
## Открытые вопросы / нюансы
|
||
|
||
- **`rimiz.ru` отдаёт 404** на host-IIS (и на VM до миграции тоже отдавал?). CMS-routing не знает этот host. Проверить mapping в БД / CMS-сайт-таблице.
|
||
- **stostayer + stostayer.old timeout** на host-IIS (`http://localhost:8090/`, `:8091`). Возможно cold-start ASP.NET, возможно реальный bug. Сейчас не разбирали — traefik для них всё ещё на VM.
|
||
- **Snolla.IdentityManager не мигрирован** — если что-то внутри CMS дёргает его через `localhost:8089`, может тихо ломаться (пока симптомов не видно).
|
||
- **VM можно глушить** только после: либо доделать stostayer на host, либо явное решение не мигрировать stayer на этот хост.
|
||
- **Phase 5 не сделан**: URL Rewrite + ARR (фикс `:4443` в редиректах CMS), Application Initialization (warm-start), log rotation `C:\inetpub\logs\`.
|
||
|
||
## Технические артефакты
|
||
|
||
- `.tasks/iis-on-host-migration.md` — детальный план фаз, обновлён со статусом Phase 1-3 = done.
|
||
- Backup конфигов traefik: `*.yml.bak-phase3-2026-05-19`.
|
||
- Скрипты Phase 2 и Phase 3 — в истории чата сессии (не сохранены отдельным файлом, идемпотентны на повторный запуск).
|
||
|
||
## Phase 4 — реорг `C:\sites\` + перенос stayer'ов (вечер 2026-05-19)
|
||
|
||
Пользователь возмутился разбросом (`C:\sites\` только для snolla, `C:\stayer\` для stayer). Реорганизация ради единой иерархии:
|
||
|
||
- `C:\sites\MoreThenCms.Web` → `C:\sites\snolla` (rename)
|
||
- `C:\stayer\MoreThenCms.Web` → `C:\sites\stostayer` (move)
|
||
- `C:\stayer\stostayer.old` → `C:\sites\stostayer.old` (move)
|
||
- `C:\stayer\Snolla.IdentityManager` → `C:\sites\snolla-identity-manager` (move + kebab-rename)
|
||
- Удалены: `C:\stayer\Mis.StoStayer.{Price,TireService,Calculator}.{Api,Web}` (sub-apps не нужны).
|
||
- `C:\stayer\` полностью удалён.
|
||
|
||
IIS sync:
|
||
- Site `MoreThenCms.Web` → переименован в `snolla` (`Set-ItemProperty IIS:\Sites\... -Name name`)
|
||
- AppPool `MoreThenCms.Web` — **rename невозможен in-place**, пересоздан как `snolla` с тем же набором properties (.NET v4.0 Integrated, `ApplicationPoolIdentity`), site rebound, старый pool удалён.
|
||
- `physicalPath` всех 3 sites обновлён под `C:\sites\<name>`.
|
||
- Web.config sitePath patches:
|
||
- `C:\sites\snolla\Web.config`: `C:\sites\MoreThenCms.Web\` → `C:\sites\snolla\`
|
||
- `C:\sites\stostayer\Web.config`: `C:\stayer\MoreThenCms.Web\` → `C:\sites\stostayer\`
|
||
- ACL re-grant + cleanup stale ACE для `IIS AppPool\MoreThenCms.Web`.
|
||
|
||
## Phase 5 — stostayer.old DB-conn патч (запутанная история conn-string'ов в stayer\)
|
||
|
||
Локальный smoke `:8091` падал в timeout. Причина: `C:\sites\stostayer.old\web.config` имел `Data Source=10.0.2.2` (адрес VBox NAT gateway, на хосте не резолвится) с user=`snolla` — фактически идентичная нашему MSSQL контейнеру конфигурация, только адрес неправильный. Patch: `10.0.2.2` → `localhost`. После — `:8091` → 200.
|
||
|
||
Это **наша ошибка** Phase 2 — пропустили patch этого файла, так как фокус был только на `MoreThenCms.Web\Web.config`.
|
||
|
||
## Phase 6 — stostayer DB-conn миграция на новый сервер (`www.stostayer.ru`)
|
||
|
||
Локальный smoke `:8090` тоже timeout — но по другой причине. `C:\sites\stostayer\Web.config` указывал на `89.253.219.2,1433` (внешний production MSSQL), оказался **полностью недоступен**: TCP timeout, ping fail, traceroute затухает на 8-м hop у `139.45.230.171`. На VM (через тот же путь) тоже не работал — пользователь подтвердил.
|
||
|
||
Пользователь предоставил новые creds: `www.stostayer.ru,1433` / `stayer_site` / `^I9D)LB)DK)8J#xBDG$t}W&_ioaT!M!LF`. Тест из не-elevated PS: TCP reachable, SQL login OK (SQL Server 2022). Patched Web.config.
|
||
|
||
**Pitfall:** после patch IIS отдавал HTTP 500. Причина — символ `&` в пароле, который **в XML является зарезервированным**. ASP.NET Web.config XML парсер падал на парсинг conn-string. Fix: `&` → `&` (XML entity escape). См. [[webconfig-password-xml-escape]].
|
||
|
||
## Phase 7 — отключение traefik routes для stayer'ов
|
||
|
||
Пользователь решил: stayer'ы наружу светить не нужно вообще (даже после миграции на хост). `stostayer.yml` и `oldstostayer.yml` переименованы в `*.yml.disabled` — traefik file-provider не подхватывает, route gone. Site'ы на хосте `:8090/:8091` остаются для возможного внутреннего использования.
|
||
|
||
Backup yml для этих изменений: `*.yml.bak-stayer-switch-2026-05-19` (содержит вариант с переключением на `:8090/:8091` — на случай если решим включить обратно).
|
||
|
||
## Phase 8 — VM savestate
|
||
|
||
После того как 100% prod-трафика идёт через host-IIS, VM `snolla-recovery` заморожена через `VBoxManage controlvm "snolla-recovery" savestate`. VMState = `saved`. Конфигурация и диски сохранены — resume за 5-10 сек если что-то понадобится. Не удалена.
|
||
|
||
## Финальное состояние (2026-05-19 конец сессии)
|
||
|
||
```
|
||
C:\sites\
|
||
├── snolla\ (was MoreThenCms.Web in C:\inetpub\wwwroot, was in vm-sites\wwwroot\MoreThenCms.Web)
|
||
├── stostayer\ (was C:\stayer\MoreThenCms.Web)
|
||
├── stostayer.old\ (was C:\stayer\stostayer.old)
|
||
└── snolla-identity-manager\ (was C:\stayer\Snolla.IdentityManager — deploy artifact, без живого consumer'а)
|
||
|
||
IIS sites/pools (имя=имя=пуло):
|
||
snolla *:80 → C:\sites\snolla (pool snolla, .NET v4.0 Integrated, AppPoolIdentity)
|
||
stostayer *:8090 → C:\sites\stostayer (pool stostayer)
|
||
stostayer.old *:8091 → C:\sites\stostayer.old (pool stostayer.old)
|
||
|
||
Connection strings:
|
||
snolla: Data Source=localhost → MSSQL container на хосте (DB MoreThenCms)
|
||
stostayer: Data Source=www.stostayer.ru,1433 (user stayer_site) → внешний SQL Server 2022
|
||
stostayer.old: Data Source=localhost → MSSQL container на хосте (DB stostayer, user snolla)
|
||
|
||
Traefik active routes: 10 главных доменов (snolla.com и др.) + rimiz.ru → host:80.
|
||
Stayer routes (stostayer.snolla.com, old.stostayer.ru) DISABLED — приватны.
|
||
Mёртвые: disk.yml, dsm.yml (192.168.1.10).
|
||
|
||
VM snolla-recovery: VMState=saved (frozen, ~92 GB на диске + ~3 GB savestate RAM dump).
|
||
```
|
||
|
||
## Открытые вопросы (что унесли в следующую сессию)
|
||
|
||
- **`rimiz.ru` отдаёт 404** на host-IIS. CMS-routing не знает этот host — нужно копнуть БД (таблица CMS-сайтов, mapping host header → site).
|
||
- **Snolla.IdentityManager** на хосте: папка перенесена, но IIS-сайт не создавался (по решению). Если CMS-код где-то дёргает `localhost:8089` или подобное — будет тихий fail. Симптомов пока нет.
|
||
- **Phase 5 (из старого плана)**: URL Rewrite + ARR для фикса `:4443` в редиректах, Application Initialization (warm-start), log rotation `C:\inetpub\logs\`. Не блокеры.
|
||
- **VM-cleanup**: если через ~неделю стабильной работы host'а проблем не будет — `VBoxManage unregistervm "snolla-recovery" --delete` освободит ~92 GB. NAT port forwards в OpenWRT (host:18080/18180/18181/18189) можно удалить.
|
||
|
||
## Связано
|
||
|
||
[[recovery-architecture-snapshot]] обновлён под полностью-host chain. [[snolla-recovery-vm]] — VMState=saved, все sites unused. [[windows-recovery-host]] — финальный layout `C:\sites\`. [[webconfig-password-xml-escape]] — новый concept про XML entity escape в conn-string'ах. [[cms-config-rewrite-pattern]] — UTF-8 BOM подтверждён ещё много раз.
|
||
|
||
---
|
||
|
||
## Phase 9 — RЕVERT (вечер 2026-05-19, после провала)
|
||
|
||
**Что случилось:** через ~10 минут после моего commit'a "done" пользователь открыл `https://www.pilorama98.ru/` → `502 Bad Gateway`. Дальше остальные домены показали `TOO_MANY_REDIRECTS`.
|
||
|
||
**Root cause** (расписан полностью в [[iis-migration-2026-05-19-postmortem]]):
|
||
- Phase 3 я patched traefik backend `host.docker.internal:18080` → `host.docker.internal:80`.
|
||
- Внутри traefik-контейнера `host.docker.internal:80` через Docker Desktop NAT резолвится **обратно в сам traefik** на его HTTP entrypoint :80 (potential Docker publish-port loopback gotcha).
|
||
- traefik `https.yml` имеет http-catchall middleware `redirect-to-https` → traefik отвечает 301 на свой же запрос → loop.
|
||
|
||
**Реактивная цепочка ошибок** (~1 час):
|
||
- Restart-WebAppPool, nuke workers, docker restart traefik → only sделали хуже (503).
|
||
- Patched `host.docker.internal:80 → 192.168.1.143:80` → тот же loop (LAN-IP через NAT тоже возвращается в traefik).
|
||
- Patched на `:8088` + добавил IIS binding → нужен `Stop+Start Website` чтобы binding applied, изначально забыл → IIS не listen → 503.
|
||
- Думал что 301 от CMS (Pitfall 5 X-Forwarded-Proto), копал CMS код — реальный источник был самим traefik (headers без `Server: Microsoft-IIS` подсказывали).
|
||
|
||
**Revert (выполнен):**
|
||
- `VBoxManage startvm "snolla-recovery"` — VM поднята из savestate (~10s + 90s warmup + recipe `ipconfig /release /renew` для застрявшего network adapter из [[vbox-windows-stability-tuning]]).
|
||
- 11 главных yml восстановлены из `*.bak-phase3-2026-05-19` (`host.docker.internal:18080` → VM).
|
||
- Stayer yml: `stostayer.yml.disabled / oldstostayer.yml.disabled` удалены, восстановлены из `*.bak-stayer-switch-2026-05-19` (`:18180/18181` → VM).
|
||
- `docker restart traefik` (file-provider не подхватил reload автоматом).
|
||
- Public smoke через VM-chain → 7/11 хостов отвечают (2 c 200, 5 с CMS-side редиректами на canonical — нормально для CMS-логики); проверено пользователем в браузере → работает.
|
||
|
||
## Финальное состояние (после revert)
|
||
|
||
Production снова на VM-chain (как было в начале сессии 2026-05-19). На хосте осталось:
|
||
- `C:\sites\{snolla, stostayer, stostayer.old, snolla-identity-manager}` — ~11 GB, **inert** (не на prod-пути)
|
||
- IIS sites/pools `snolla, stostayer, stostayer.old` — не получают трафика (traefik backend назад на VM)
|
||
- traefik backups: `*.bak-phase3-2026-05-19`, `*.bak-stayer-switch-2026-05-19`, `*.bak-hostip-2026-05-19`
|
||
- VM `snolla-recovery` — running, IIS активен, обслуживает 11 главных доменов + 2 stayer публично через port forwards.
|
||
|
||
**Артефакты для следующей попытки** (НЕ удалять):
|
||
- 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, отдельная задача.
|
||
|
||
## Phase 11 — close-out 2026-05-21 (~36h soak)
|
||
|
||
Soak window 2026-05-19 22:00 MSK → 2026-05-21 ~08:00 MSK ≈ 36 hours. Verify:
|
||
|
||
- **Traefik:** `Up 38 hours` (`docker ps`) — zero restarts, zero unscheduled bouncing.
|
||
- **w3wp.exe** (IIS worker для `snolla` site): PID 10432, CreationDate 2026-05-20 23:19:21 MSK, uptime 8.8h. Это **scheduled IIS app pool recycle** (default 1740 min ≈ 29h), не crash — нормальное поведение pool'а после ~29h работы. Память 522 MB.
|
||
- **HTTPS smoke** 11 заявленных hosts через `docker exec traefik wget --spider --server-response https://<host>/`:
|
||
|
||
| Host | Code | Server | Verdict |
|
||
|---|---|---|---|
|
||
| `emspb.ru` | 301→www | Microsoft-IIS/10.0 | ✅ |
|
||
| `snolla.com` | 301→on.snolla | Microsoft-IIS/10.0 | ✅ |
|
||
| `on.snolla.com` | 200 | Microsoft-IIS/10.0 | ✅ |
|
||
| `pilorama98.ru` | 301→www | Microsoft-IIS/10.0 | ✅ |
|
||
| `labtools.ru` | 301→www | Microsoft-IIS/10.0 | ✅ |
|
||
| `labtools.pro` | 301→www | Microsoft-IIS/10.0 | ✅ |
|
||
| `tandemmebel.ru` | 301→www | Microsoft-IIS/10.0 | ✅ |
|
||
| `kupimknigi.spb.ru` | 200 | Microsoft-IIS/10.0 | ✅ |
|
||
| `maljarka.ru` | — | DNS bad address | ⚠️ off-infra (nslookup 8.8.8.8 → no A record) |
|
||
| `sestech.ru` | — | TLS cert `CN=*.domainparking.ru` (expired 2026-05-13) | ⚠️ off-infra (domain parking provider) |
|
||
| `ics-artmaterials.com` | 200 | `nginx-reuseport/1.21.1` | ⚠️ off-infra (A→87.236.16.28, мигрирован на сторонний WP-хостинг) |
|
||
|
||
**Итог:** 8/8 наших sites зеленые. 3 hostname'а из исходного списка task'а оказались **уже не на нашей инфраструктуре** — DNS либо снят, либо переключен на сторонние хостинги. Это не regression миграции; эти domains надо просто убрать из traefik/IIS routing'а как dead.
|
||
|
||
Decisions:
|
||
- iis-host migration close-out: **DONE 2026-05-21**.
|
||
- VM `snolla-recovery`: готова к savestate (soak passed, zero rollbacks). User-side savestate решает отдельно.
|
||
- 3 off-infra domains: новая задача — `iis-traefik-dead-routes-cleanup` (low prio).
|
||
|
||
## Артефакты Phase 11
|
||
|
||
- `.tasks/STATUS.md` — task → 🟢 done.
|
||
- (existing) traefik bak-серия `.bak-pre-attempt2-2026-05-19` — оставить ещё неделю (atomic revert на случай unforeseen regression).
|