10/11 main domains now served by native host IIS via traefik (C:\sites\MoreThenCms.Web on *:80). rimiz.ru -> 404 (CMS-side), stostayer/stostayer.old technically deployed but timeout locally, traefik for stayer kept on VM. Phase 4-5 open. - STATUS: ready -> paused with detailed where-I-stopped - iis-on-host-migration: completed steps + decisions log + status block - NEXT-SESSION-PROMPT: rewritten with current state + 4 next-task options Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
10 KiB
10 KiB
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) - ✅ .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-сайты из VMC:\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.IdentityManagerstostayer(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) - Настроить log rotation для C:\inetpub\logs\
- Application Initialization (для warm-start CMS) — IIS Optional Feature, autostart сайтов
Open questions
- CMS-код использует абсолютные пути типа
C:\inetpub\wwwroot\MoreThenCms.Web\(видели в Web.config<add key="sitePath" .../>)? Если да — путь должен остаться, либо обновить. - Authentication / IIS Application Identity — какая учётка должна крутить app pool? (LocalSystem? NetworkService? IIS AppPool<sitename>?)
- Нужен ли .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
- Pulled VM sites to host (49 минут tar+ssh, 11 GB total)
- IIS на хосте установлен (в рамках recovery, ещё нативно не использовался)
- Phase 1 — discovery (2026-05-19): VM сайты/пулы/vdirs/features через SSH + appcmd, host IIS features через elevated DISM, source grep на hardcoded paths. См.
.wiki/sources/iis-host-migration-2026-05-19.md. - Phase 2 — миграция MoreThenCms.Web (2026-05-19):
C:\sites\MoreThenCms.Web(8.7 GB robocopy), Web.config patch (sitePath+ conn → localhost, UTF-8 BOM), AppPool + Website на*:80, ACL:(OI)(CI)MдляIIS AppPool\MoreThenCms.Web. Default Web Site остановлен. Smoke test черезlocalhostс Host header — 10/11 хостов отвечают (rimiz.ru → 404, как issue ниже). - Phase 2 — stostayer / stostayer.old (2026-05-19, частично): сайты созданы на
:8090/:8091→C:\stayer\MoreThenCms.Web/C:\stayer\stostayer.old, AppPools созданы, ACL поставлен. Но локально оба отвечают timeout — рантайм-проблема не разбиралась. - Phase 3 — traefik switch (2026-05-19): 11 yml пропатчены
host.docker.internal:18080→host.docker.internal:80, traefik file-provider auto-reload, public smoke черезhttps://localhost:4443/— 10/11 хостов → HTTP 200, rimiz.ru → 404. Stostayer/oldstostayer backend в traefik не трогали (остаются на VM).
Решения (decisions log дополнен)
- 2026-05-19: Snolla.IdentityManager не мигрируется — пользователь подтвердил «не нужен» (Q-C в сессии). Если что-то внутри CMS дёргает его по
localhost:8089— увидим в логах, тогда вернёмся. - 2026-05-19: Sub-apps stostayer.old (
/calc,/price,/price/tireService) не мигрируются — пользователь подтвердил «не нужны». - 2026-05-19: stostayer.connection-string на 89.253.219.2 не трогаем (Q-B пользователя «не трогай, так надо»). Это внешний production MSSQL для stayer-инфраструктуры, не наш контейнер.
- 2026-05-19: AppPool identity = ApplicationPoolIdentity для всех 3 пулов (default outside SCM, безопасно). ACL
:(OI)(CI)M(Modify) рекурсивно на site root. - 2026-05-19: Path strategy = C:\sites\ (не
C:\inetpub\wwwroot\) — пользователь выбрал (б) в Q1.
Status
- ✅ MoreThenCms.Web на хосте обслуживает 10 главных доменов через traefik.
- ⏳ rimiz.ru → 404 (CMS-side mapping issue).
- ⏳ stostayer / stostayer.old: технически перенесены, runtime fail на хосте, prod-трафик пока на VM.
- ⏳ Phase 4 (cleanup VM) — пока нельзя, нужны stostayer.
- ⏳ Phase 5 (URL Rewrite + ARR + log rotation + AppInit) — bonus, можно сразу.
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.