# iis-on-host-migration ## Goal Перенести IIS-сайты MoreThenCms из VirtualBox VM (`snolla-recovery`) на нативный IIS Windows-хоста. VM остаётся как hot fallback на первое время; после успешного нативного-запуска — выключаем VM, освобождаем 4 GB RAM + ~92 GB диска. **Зачем:** VM на VBox = лишний слой нестабильности (видели один network hang). Нативный IIS на хосте — проще, быстрее, без NAT-форвардов и VBox-капризов. Контейнеры MSSQL/MinIO/etc. уже на этом же хосте — устраняем сетевой роутинг. ## Что у нас уже есть - ✅ IIS установлен на хосте (W3SVC running, default site empty, [`.wiki/entities/windows-recovery-host`](../.wiki/entities/windows-recovery-host.md)) - ✅ .NET Framework 4.8.1 на хосте - ✅ Полная копия `C:\inetpub\wwwroot\` из VM → `C:\nas-recovery\vm-sites\wwwroot\` (8.69 GB) - ✅ Полная копия `C:\stayer\` из VM → `C:\nas-recovery\vm-sites\stayer\` (2.21 GB) - ✅ MSSQL контейнер на host:1433 (5 production DB) - ✅ MinIO на host:9000, Elasticsearch на host:9200, imgproxy на host:8787/8788 - ✅ Исходники CMS в `C:\Users\vitya\projects\MoreThenCms\` (Git репо) - ✅ Traefik с 13 client routes (сейчас target = `host.docker.internal:18080` = VM) ## Key files - `C:\nas-recovery\vm-sites\wwwroot\` — IIS-сайты из VM - `C:\nas-recovery\vm-sites\stayer\` — stostayer-проекты - `C:\inetpub\wwwroot\` — целевое расположение на хосте - `C:\Users\vitya\projects\docker\diskstation\traefik\data\custom\*.yml` — backends, нужно переключить с `host.docker.internal:18080` на `localhost:80` (или какие-то local IIS-bindings) - `Web.config` файлы — connection strings уже патчены на `10.0.2.2`, нужно вернуть на `localhost` или `127.0.0.1` для нативного IIS ## План этапов ### Phase 1 — Анализ и подготовка - Изучить IIS site bindings в VM (MoreThenCms.Web `*:80`, Snolla.IdentityManager `*:80`, stostayer `*:8080`, stostayer.old `*:8081`) - Решить port-mapping на хосте — оставлять 80? Или другие порты, traefik на 80/443 переадресует? - Изучить, какие IIS modules/features нужны (URL Rewrite, ARR, обязательные .NET runtimes — может потребоваться доставить) ### Phase 2 — Импорт сайтов на хост - Скопировать `C:\nas-recovery\vm-sites\wwwroot\*` → `C:\inetpub\wwwroot\` (или другой root) - Скопировать `C:\nas-recovery\vm-sites\stayer\` → `C:\stayer\` - Создать application pools (`.NET v4.5` или эквивалент) для каждого сайта в IIS Manager - Создать sites в IIS: - `MoreThenCms.Web` (port 80 / другой) - `Snolla.IdentityManager` - `stostayer` (port 8080) - `stostayer.old` (port 8081) - Web.config patch: `Data Source=10.0.2.2` → `Data Source=localhost` (или `127.0.0.1` / `.\` ; UTF-8 BOM!) ### Phase 3 — Перенос на хост IIS, тест - Stop VM (но не удалять!) - Update traefik backends в `data/custom/*.yml`: - `http://host.docker.internal:18080/` → `http://host.docker.internal:80/` (или какой порт IIS использует) - `:18180` → `:8080`, `:18181` → `:8081` - traefik restart - Прокликать все 11 клиентских доменов из публичного интернета - Убедиться что .NET Framework 4.8.1 справляется, нет missing assemblies, нет permission issues на App_Data / temp folders ### Phase 4 — Cleanup VM - Когда стабильно ~неделя на хост-IIS — выключить VM окончательно - `VBoxManage controlvm "snolla-recovery" poweroff` - Удалить port forwards в OpenWRT, которые больше не нужны (host:18080, host:18180, etc.) — это уже не traefik backend - (Опционально) удалить VM из VBox: `VBoxManage unregistervm "snolla-recovery" --delete`. Это освобождает 92 GB на C:. - Удалить `C:\nas-recovery\backup\snolla\snolla.ova` (42.5 GB) и `C:\nas-recovery\vm-sites\` (11 GB) — backup уже не нужен. ### Phase 5 — Бонусы - Установить **URL Rewrite + ARR** для нормальной обработки X-Forwarded-Proto headers (fix CMS-редиректа с `:4443` в URL — см. [`.wiki/concepts/traefik-on-windows-docker-desktop`](../.wiki/concepts/traefik-on-windows-docker-desktop.md)) - Настроить log rotation для C:\inetpub\logs\ - Application Initialization (для warm-start CMS) — IIS Optional Feature, autostart сайтов ## Open questions - [ ] CMS-код использует абсолютные пути типа `C:\inetpub\wwwroot\MoreThenCms.Web\` (видели в Web.config ``)? Если да — путь должен остаться, либо обновить. - [ ] Authentication / IIS Application Identity — какая учётка должна крутить app pool? (LocalSystem? NetworkService? IIS AppPool\?) - [ ] Нужен ли .NET Framework Repair / SAC update перед миграцией? - [ ] Что с storage providers (Azure-SDK adapter в CMS)? — Связано с открытым вопросом о MinIO/Azure, что пользователь обещал прояснить. ## Decisions log - 2026-05-19: задача поставлена после успешного recovery в VM. VM показала себя нестабильной (один network hang за день uptime), решено мигрировать на нативный IIS как более простой и предсказуемый стек. ## Completed steps - [x] Pulled VM sites to host (49 минут tar+ssh, 11 GB total) - [x] IIS на хосте установлен (в рамках recovery, ещё нативно не использовался) ## Notes - VM не удалять до конца Phase 3 — это working fallback. Только после двух недель стабильной работы host-IIS. - Git push в gitea невозможен пока — gitea был на мёртвой синке. Восстановление gitea — отдельная задача (есть бэкап `/docker/gitea/` 2.6 GB на kreknin-синке, можно поднять локально или временно класть code в другое место). - При работе с Web.config — **обязательно UTF-8 BOM** через `[System.IO.File]::WriteAllText` с `[System.Text.UTF8Encoding]::new($true)`. Иначе IIS 500.19. Детали в [`.wiki/concepts/cms-config-rewrite-pattern`](../.wiki/concepts/cms-config-rewrite-pattern.md).