tasks(vds-migration): decompose umbrella → 3 child tasks
- mssql-vds-migration ⚪: Express edition, BACKUP/RESTORE method, mssql.kzntsv.site:1433 - minio-imgproxy-vds-migration ⚪: MinIO upgrade 2020→latest, mc mirror, includes imgproxy+nginx - iis-cutover-to-vds-services 🔵: atomic web.config repoint (1 file → 11 hosts), blocked on both migrations - umbrella mssql-minio-migration-to-vds 🟢: decomposed (kept for history) Discovery: 5 prod DBs ≤ 968 MB (Express OK), .ldf logs 12 GB → SHRINKFILE pre-cutover. VDS: 79 GB free, 5.8 GB RAM avail. ownCloud capped 1G. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
# Admin Task Board
|
# Admin Task Board
|
||||||
_Updated: 2026-05-22 (owncloud-vds-deploy 🟢 — 25 044 объектов / 26 GB live, все 6 large-file холдауты залиты VDS-side curl loopback'ом; 60s upload-timeout finding закреплён в [`ocis-on-vds-deploy-recipe`](../.wiki/concepts/ocis-on-vds-deploy-recipe.md) §Gotcha 5)_
|
_Updated: 2026-05-22 (mssql-minio-migration-to-vds декомпозирована → 3 child tasks: `mssql-vds-migration` ⚪ + `minio-imgproxy-vds-migration` ⚪ + `iis-cutover-to-vds-services` 🔵. Discovery: 5 prod DBs все ≤ 968 MB <10 GB Express OK; .ldf logs 12 GB → SHRINKFILE pre-cutover; MinIO 3 GB + image 2020 (CVE) → upgrade + `mc mirror`; imgproxy stack едет вместе. **IIS cutover — финальный шаг ради которого всё затевалось**: 11 CMS hosts через snolla catch-all = atomic edit одного web.config. VDS: 79 GB disk free, 5.8 GB RAM available, ownCloud mem_limit 1G applied.)_
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Status legend:
|
Status legend:
|
||||||
@@ -517,13 +517,49 @@ User confirmed close by inspection: "Close review as no-new-findings (Recommende
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## ⚪ [mssql-minio-migration-to-vds] — Фаза 2 CMS backup. Перенести MSSQL контейнер + MinIO с windows-recovery-host на vds-kzntsv. Achieves target RPO 1ч через интеграцию с существующим `vds-backup-rsync-kreknin` pipeline (tx log backups каждые 60 мин в существующий rsync→kreknin). Снимает SPOF с домашней машины для критических CMS-данных.
|
## 🟢 [mssql-minio-migration-to-vds] — декомпозирована 2026-05-22 на две независимые таски
|
||||||
|
|
||||||
После завершения — списать `cms-stopgap-backup-daily` cron на windows-host.
|
**Closed:** 2026-05-22 — Discovery prep сессия (windows-side docker ps + sizes + VDS docker ps + stats) выявила что MSSQL и MinIO имеют разные мигратные паттерны (BACKUP/RESTORE vs `mc mirror`), разные окна простоя, разные rollback, разный risk profile (Express edition limit check vs MinIO 5-year upgrade). User decided: split на две таски.
|
||||||
|
|
||||||
|
**Children:**
|
||||||
|
- `mssql-vds-migration` ⚪ — MSSQL only, Express edition prod, SHRINKFILE-cleanup → BACKUP/RESTORE → traefik TCP `mssql.kzntsv.site:1433`.
|
||||||
|
- `minio-imgproxy-vds-migration` ⚪ — MinIO upgrade `2020-07-13` → latest + imgproxy + imgproxy-nginx, `mc mirror`, traefik HTTPS `minio.vds.kzntsv.site` (+ console subdomain).
|
||||||
|
|
||||||
|
Original umbrella `.tasks/mssql-minio-migration-to-vds.md` сохранён для history (acceptance/decisions/risks merged в children).
|
||||||
|
**Branch:** n/a
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚪ [mssql-vds-migration] — Перенести MSSQL с windows-recovery-host на vds-kzntsv. Express edition (prod, 10 GB/DB limit OK для всех 5 prod DBs), `mssql.kzntsv.site:1433` через traefik TCP passthrough.
|
||||||
|
|
||||||
|
Method: BACKUP DATABASE WITH COMPRESSION, COPY_ONLY → scp → RESTORE на VDS. Кросс-edition (Developer→Express). Pre-cutover SHRINKFILE на .ldf срежет 12 GB logs (warning: ломает log-chain до следующего FULL — приемлемо в migration window).
|
||||||
|
|
||||||
**Status:** ready
|
**Status:** ready
|
||||||
**Where I stopped:** (not started)
|
**Where I stopped:** (not started)
|
||||||
**Next action:** См. `mssql-minio-migration-to-vds.md` — full acceptance (8 items) + risks + open questions. Major task (1-2 недели realistic). Разбить на sub-phases: (a) MSSQL container deploy на VDS + restore from backup, (b) connection string change + smoke 8 hosts, (c) MinIO migration через `mc mirror`, (d) backup pipeline integration в `/opt/stacks/backup/scripts/run.sh`. **Pre-cutover benchmark обязателен** (admin assets UI / search / catalogs) — WAN latency 10-30ms vs localhost. Spawn'd by [resilience-roadmap-design] workshop pass 1 2026-05-21.
|
**Next action:** См. `mssql-vds-migration.md` — full acceptance (9 items) + risks + open questions. Sub-phases: (1) SHRINKFILE cleanup на source, (2) BACKUP 5 DBs → scp → RESTORE на VDS, (3) traefik TCP entrypoint :1433 + ufw, (4) DNS A `mssql.kzntsv.site`, (5) CMS connection-string repoint + smoke 8 hosts, (6) backup pipeline integration (mssql_dump_full daily + mssql_tx_log_backup hourly → достигает RPO 1ч), (7) source decommission после 48ч uptime. **Pre-cutover benchmark обязателен** (WAN 10-30ms vs localhost). После first VDS backup-pipeline run — списать [cms-stopgap-backup-daily]. Spawn'd by [mssql-minio-migration-to-vds] decomposition 2026-05-22.
|
||||||
|
**Branch:** n/a
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚪ [minio-imgproxy-vds-migration] — Перенести MinIO + imgproxy + imgproxy-nginx с windows-recovery-host на vds-kzntsv. Заодно **upgrade MinIO** `RELEASE.2020-07-13` (5 лет, CVE) → `minio/minio:latest`. `minio.vds.kzntsv.site` + `minio-console.vds.kzntsv.site` через traefik HTTPS.
|
||||||
|
|
||||||
|
Method: snapshot bind-mount source (rollback insurance) → empty new MinIO на VDS → `mc mirror old→new` → fallback `aws s3 sync` если format-compat ломается → repoint CMS endpoints + imgproxy через internal `shared-dbs` network (`http://minio:9000`).
|
||||||
|
|
||||||
|
**Status:** ready
|
||||||
|
**Where I stopped:** (not started)
|
||||||
|
**Next action:** См. `minio-imgproxy-vds-migration.md` — full acceptance (9 items) + risks + open questions. Sub-phases: (1) snapshot source bind-mount, (2) deploy stack на VDS (minio + imgproxy + imgproxy-nginx, networks proxy+shared-dbs), (3) traefik HTTPS routes + LE certs + DNS A-records, (4) `mc mirror` per-bucket with verify, (5) repoint CMS image endpoints + smoke 8 sites, (6) backup pipeline integration (minio_mirror daily — recommend rsync over mc mirror для simplicity), (7) source decommission после 48ч. **Open compat risk:** xl.meta format gap 5 лет — dry-run `mc mirror --dry-run` сначала, fallback plan B (same old image на VDS, upgrade later). Spawn'd by [mssql-minio-migration-to-vds] decomposition 2026-05-22.
|
||||||
|
**Branch:** n/a
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚪ [iis-cutover-to-vds-services] — **Финальный cutover** IIS на windows-recovery-host: repoint CMS conn-strings с `localhost,1433` → `mssql.kzntsv.site,1433` + `localhost:9000` → `minio.vds.kzntsv.site`. Это **то ради чего всё затевалось** — миграции MSSQL/MinIO бесполезны без этого шага.
|
||||||
|
|
||||||
|
Atomic edit: один `C:\sites\snolla\web.config` обслуживает 11 CMS-хостов через traefik catch-all (`*:8089`) + `stostayer.old\web.config` (local-only). `iisreset` → 11 хостов мигрируют разом. Rollback = revert backup.
|
||||||
|
|
||||||
|
**Status:** blocked (waiting on `mssql-vds-migration` + `minio-imgproxy-vds-migration`)
|
||||||
|
**Where I stopped:** (not started)
|
||||||
|
**Next action:** См. `iis-cutover-to-vds-services.md` — full acceptance (11 items). Sub-phases: (1) audit config locations (`Get-ChildItem -Recurse C:\sites -Include web.config,appsettings.*.json | Select-String 'localhost,1433|localhost:9000'`) → mapping site→DB→endpoint, (2) pre-cutover benchmark (admin/assets/getList + search + каталоги) → baseline, (3) backup web.config'ов, (4) edit conn-strings (`localhost,1433` → `mssql.kzntsv.site,1433;TrustServerCertificate=true`), (5) edit MinIO/imgproxy endpoints (audit-driven), (6) iisreset + smoke 8 hosts, (7) post-cutover benchmark <2x degradation gate, (8) MinIO write smoke (admin upload → mc ls verify + imgproxy render), (9) 48ч soak, (10) decommission source containers + списать `cms-stopgap-backup-daily`. **Open risk:** если MinIO/imgproxy URLs hardcoded в скомпилированных DLL — fallback: оставить `imgproxy-nginx` на windows-host, transparent proxy на VDS MinIO. Spawn'd by user-poke 2026-05-22 («IIS перенастроить!»).
|
||||||
|
**Blocker:** mssql-vds-migration + minio-imgproxy-vds-migration
|
||||||
**Branch:** n/a
|
**Branch:** n/a
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
91
.tasks/iis-cutover-to-vds-services.md
Normal file
91
.tasks/iis-cutover-to-vds-services.md
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
# iis-cutover-to-vds-services
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
Перенастроить IIS на [[../entities/windows-recovery-host]] так чтобы CMS sites обращались к **MSSQL/MinIO/imgproxy на VDS** вместо localhost-контейнеров. Это **финальный шаг** ради которого всё затевалось — миграция MSSQL/MinIO бессмысленна без репойнта IIS.
|
||||||
|
|
||||||
|
**Depends on:**
|
||||||
|
- `mssql-vds-migration` — MSSQL должен быть live на `mssql.kzntsv.site:1433` с restored DBs
|
||||||
|
- `minio-imgproxy-vds-migration` — MinIO + imgproxy live на `minio.vds.kzntsv.site` / `imgproxy.kzntsv.site`
|
||||||
|
|
||||||
|
Cutover атомарный: один web.config edit + iisreset = 11 хостов мигрируют разом. Rollback = revert backup.
|
||||||
|
|
||||||
|
## Key files / refs
|
||||||
|
- **Catch-all IIS site `snolla`** (`*:80` + `*:8089`, [[../.wiki/concepts/recovery-architecture-snapshot]] §"Host IIS configuration") — `C:\sites\snolla\web.config` обслуживает **11 CMS hosts** через traefik backend `host.docker.internal:8089`:
|
||||||
|
- snolla.com + 10 *.snolla.com subdomains
|
||||||
|
- labtools.ru / labtools.pro
|
||||||
|
- pilorama98.ru, tandemmebel.ru, emspb.ru, kupimknigi.spb.ru
|
||||||
|
- maljarka.tandemmebel.ru, sestech.ru, ics-artmaterials.com
|
||||||
|
- **Local-only IIS sites** (не через traefik, local-only):
|
||||||
|
- `stostayer` (`*:8090`) — `C:\sites\stostayer\web.config`, conn уже `www.stostayer.ru,1433` (external — может не требовать изменений)
|
||||||
|
- `stostayer.old` (`*:8091`) — `C:\sites\stostayer.old\web.config`, conn `localhost,1433` → требует repoint
|
||||||
|
- **Source MSSQL endpoint** (current): `Data Source=localhost,1433` (для snolla + stostayer.old)
|
||||||
|
- **Target MSSQL endpoint** (new): `Data Source=mssql.kzntsv.site,1433;TrustServerCertificate=true` (self-signed cert через traefik TCP passthrough)
|
||||||
|
- **MinIO/imgproxy CMS settings** — точное место в config TBD (audit step 1). Возможно `appSettings` в web.config или отдельный config-файл (CMS уровня).
|
||||||
|
- **Per-DB mapping** (какой site какую DB трогает — verify через `sp_helpdb` или audit web.config'ов):
|
||||||
|
- snolla → likely `MoreThenCms` + `stostayer` (один CMS на много sites)
|
||||||
|
- stayer sites → `StayerCalculator` / `StayerPrice` / `TireService`
|
||||||
|
|
||||||
|
## Acceptance
|
||||||
|
1. **Audit config locations:**
|
||||||
|
- `Get-ChildItem -Recurse C:\sites -Include web.config,appsettings.*.json,*.config | Select-String -Pattern 'localhost,1433|localhost:9000|localhost:8788|Data Source|connectionString'`
|
||||||
|
- Документировать в task'е (или в `.wiki/concepts/cms-config-locations.md`): какой site какой config trогает, какие conn-strings, какие MinIO/imgproxy refs.
|
||||||
|
2. **Pre-cutover benchmark** (mandatory, см. risks в `mssql-vds-migration`):
|
||||||
|
- Прогнать на каждом hot-path до cutover (LOCALHOST baseline): admin/assets/getList, search, каталоги. Сохранить в `.wiki/sources/iis-cutover-benchmark-<date>.md`.
|
||||||
|
- Pass criteria: после cutover degradation <2x. Если worse — discuss с user перед commit.
|
||||||
|
3. **Backup configs:**
|
||||||
|
```powershell
|
||||||
|
Get-ChildItem C:\sites\*\web.config | %{ Copy-Item $_ "$($_.FullName).bak-pre-vds-cutover-$(Get-Date -Format yyyyMMdd)" }
|
||||||
|
```
|
||||||
|
4. **Edit conn-strings** в `C:\sites\snolla\web.config` (catch-all для 11 хостов) + `C:\sites\stostayer.old\web.config`:
|
||||||
|
- `localhost,1433` → `mssql.kzntsv.site,1433`
|
||||||
|
- Добавить `;TrustServerCertificate=true` (self-signed TLS через traefik passthrough)
|
||||||
|
- Если `Encrypt=False` явно стоит — оставить (Encrypt=True + TrustServerCertificate ОК тоже, но fewer changes safer)
|
||||||
|
- `stostayer` (`www.stostayer.ru,1433`) — оставить как есть (уже external, не наш scope)
|
||||||
|
5. **Edit MinIO/imgproxy endpoints** (после step 1 audit точные места known):
|
||||||
|
- `localhost:9000` → `minio.vds.kzntsv.site` (HTTPS) для S3 calls из CMS
|
||||||
|
- `localhost:8788` → `imgproxy.kzntsv.site` для image-proxy URL'ов (если hardcoded; idealistic — через `IMGPROXY_BASE_URL` env)
|
||||||
|
6. **Cutover:**
|
||||||
|
- `iisreset /restart` (или `Restart-WebAppPool snolla` если selective).
|
||||||
|
- Smoke 8 priority hosts (verified live в `[iis-on-host-migration]` close-out): `emspb / snolla / on.snolla / pilorama98 / labtools.ru / labtools.pro / tandemmebel / kupimknigi` — каждый 200 OK + asset loading + admin login (если scope).
|
||||||
|
- admin/assets/getList на одном из них — hot-path verify.
|
||||||
|
7. **Post-cutover benchmark** — те же запросы что в step 2, сравнить latency. Documented в same `.wiki/sources/iis-cutover-benchmark-<date>.md`.
|
||||||
|
8. **MinIO write smoke** — загрузить тестовый asset через admin UI → verify в VDS MinIO (`mc ls new/<bucket>`), убедиться что imgproxy его рендерит через `imgproxy.kzntsv.site`.
|
||||||
|
9. **48ч soak**:
|
||||||
|
- Monitoring через existing `vds-ops` ntfy topic + manual phone check 8 hosts на 24ч / 48ч марках.
|
||||||
|
- Если regression — atomic revert (см. notes).
|
||||||
|
10. **Source decommission** (через 48ч green):
|
||||||
|
- На windows-host: `docker stop mssql minio imgproxy imgproxy-nginx` (через неделю → `docker rm + volume rm`).
|
||||||
|
- Списать `cms-stopgap-backup-daily` cron (теперь VDS backup pipeline покрывает).
|
||||||
|
11. **Documented** в [[../.wiki/concepts/iis-cutover-to-vds-services]] (создать): pre/post architecture diagrams, edit-diff'ы конфигов, benchmark numbers, rollback recipe.
|
||||||
|
|
||||||
|
## Decisions
|
||||||
|
- **Cutover style: atomic** (не gradual canary). 1 web.config edit → iisreset → 11 хостов мигрируют разом. Rationale: snolla catch-all = единая точка изменения, gradual невозможен без дублирования IIS sites (overkill).
|
||||||
|
- **TLS:** `TrustServerCertificate=true` в conn-string (self-signed cert через traefik passthrough). Permanent fix позже через LE-cert extract в DBs (см. [[vds-kzntsv-bootstrap]] Open questions).
|
||||||
|
- **stostayer site (external `www.stostayer.ru`)** не трогаем — уже external endpoint, отдельный scope.
|
||||||
|
- **maljarka.tandemmebel.ru 502 bug** не блокер этой таски (existing issue, [[../.tasks/iis-traefik-dead-routes-cleanup]] side-finding, отдельная CMS-task'а в MoreThenCms).
|
||||||
|
|
||||||
|
## Open questions (решаются audit step 1)
|
||||||
|
- [ ] **MinIO/imgproxy конфигурация** — где живёт endpoint config? В web.config `<appSettings>` или отдельный JSON / DLL config? Если hardcoded в скомпилированной DLL — рестарт CMS не поможет, нужен rebuild. См. [[../.wiki/concepts/cms-admin-assets-root-folder-seed]] §"Долгосрочный TODO" — это известная техдыра.
|
||||||
|
- [ ] **Per-site DB mapping** — какой web.config какую MSSQL DB указывает? Audit step 1 даст карту.
|
||||||
|
- [ ] **HTTPS для MSSQL conn-string** — `Encrypt=True;TrustServerCertificate=true` vs `Encrypt=False`? Текущие conn-strings в snolla web.config — unknown, audit показиет.
|
||||||
|
|
||||||
|
## Risks
|
||||||
|
- **Hardcoded DLL endpoints** — если MinIO/imgproxy URLs запечены в скомпилированных CMS DLL, repoint требует rebuild → build env вопрос. **Mitigation:** audit step 1 покажет; если hardcoded — fallback вариант: оставить imgproxy-nginx на windows-host, проксировать через него на VDS MinIO (transparent для CMS).
|
||||||
|
- **WAN latency** — admin/assets/getList sensitive (большие в-памяти выборки). 10-30ms vs localhost. Pre/post benchmark обязателен. Если degradation >2x — обсуждать query optimization vs retreat.
|
||||||
|
- **TLS chain** — self-signed cert через traefik passthrough требует `TrustServerCertificate=true` или import cert в Windows trust store. Первое проще, второе secure-er. Choose first для migration, secure-fix позже.
|
||||||
|
- **DNS propagation** — `mssql.kzntsv.site` DNS должен propagate ДО iisreset. User уже сделал A-record (2026-05-22). TTL 300s default REGRU → 5 min wait после propagate-check (`Resolve-DnsName mssql.kzntsv.site`).
|
||||||
|
- **MinIO bucket policy / CORS** — если CMS делает PUT через browser-direct upload → CORS policy на VDS MinIO должна включать domain'ы клиентских сайтов. Verify в smoke step 8.
|
||||||
|
- **Cutover failure rollback delay** — revert web.config + iisreset ~30 sec. Если windows-host MSSQL container остановлен — rollback fails. **Mitigation:** keep windows-host containers running 48ч (acceptance 10 это закладывает).
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
- **Branch:** master (per project-discipline rule 2 — no feature branches без user approval).
|
||||||
|
- **Atomic revert:**
|
||||||
|
```powershell
|
||||||
|
Get-ChildItem C:\sites\*\web.config.bak-pre-vds-cutover-* | %{
|
||||||
|
$orig = $_.FullName -replace '\.bak-pre-vds-cutover-\d+$',''
|
||||||
|
Copy-Item $_.FullName -Destination $orig -Force
|
||||||
|
}
|
||||||
|
iisreset /restart
|
||||||
|
```
|
||||||
|
Затем убедиться что windows-host MSSQL + MinIO + imgproxy containers всё ещё running. Если уже остановлены — `docker start mssql minio imgproxy imgproxy-nginx`.
|
||||||
|
- **Why this task exists separately from migrations:** разные skill-sets (migrations = Linux/docker/VDS; cutover = IIS/web.config/Windows), разные failure-modes, разные rollback-paths, разное окно работы (migrations можно делать в любое время; cutover = maintenance window). Splitting позволяет migrations завершиться + soak без давления на cutover-timing.
|
||||||
69
.tasks/minio-imgproxy-vds-migration.md
Normal file
69
.tasks/minio-imgproxy-vds-migration.md
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# minio-imgproxy-vds-migration
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
Перенести MinIO + imgproxy + imgproxy-nginx контейнеры с [[../entities/windows-recovery-host]] на [[../entities/vds-kzntsv]]. Заодно **upgrade MinIO** с `RELEASE.2020-07-13` (5 лет, куча CVE) на `minio/minio:latest`. Доступ снаружи через `minio.vds.kzntsv.site` (S3 API + console).
|
||||||
|
|
||||||
|
Это **MinIO+imgproxy половина** umbrella'ы `mssql-minio-migration-to-vds` (декомпозирована 2026-05-22). Вторая половина — `mssql-vds-migration`.
|
||||||
|
|
||||||
|
## Key files / refs
|
||||||
|
- **Source MinIO:** docker container `minio` на windows-recovery-host, image `minio/minio:RELEASE.2020-07-13T18-09-56Z`, bind `C:\Users\vitya\projects\docker\diskstation\minio\data` → `/data`, ~3 GB.
|
||||||
|
- **Source imgproxy:** docker container `imgproxy`, image `darthsim/imgproxy`, port 8787:8080. Зависит от MinIO как S3 backend.
|
||||||
|
- **Source imgproxy-nginx:** docker container `imgproxy-nginx`, image `nginx:alpine`, port 8788:80. Reverse-proxy перед imgproxy с caching.
|
||||||
|
- **Target stack:** `/opt/stacks/storage/minio-imgproxy/{docker-compose.yml,.env,data,nginx-cache,nginx.conf}` на VDS.
|
||||||
|
- **Target MinIO image:** `minio/minio:latest` (или pinned tag `RELEASE.2025-*`).
|
||||||
|
- **CMS endpoints:**
|
||||||
|
- MinIO S3: `localhost:9000` → `minio.vds.kzntsv.site` (HTTPS) для external, `http://minio:9000` для inter-container на VDS через `shared-dbs` network.
|
||||||
|
- imgproxy: `localhost:8788` → `imgproxy.kzntsv.site` (если CMS реверс-проксит) или прямо в CMS-template URL.
|
||||||
|
|
||||||
|
## Decisions
|
||||||
|
- **Upgrade MinIO** (user 2026-05-22, conditional «если ничего не сломает»). Migration via `mc mirror old-minio → new-minio`. Если совместимость bucket-format ломается → fallback `aws s3 sync`. **Rollback ready** через сохранённый snapshot bind-mount data.
|
||||||
|
- **imgproxy + imgproxy-nginx** едут вместе — `IMGPROXY_S3_ENDPOINT` поменять на `http://minio:9000` (internal через `shared-dbs`), не external — экономит latency и не гоняет S3 traffic через traefik.
|
||||||
|
- **Hostname: `minio.vds.kzntsv.site`** (user 2026-05-22). S3 API + Console на одном subdomain (MinIO 2022+ split на :9000 API + :9001 console — два под-роута через traefik PathPrefix или два subdomain).
|
||||||
|
|
||||||
|
## Acceptance
|
||||||
|
1. **Stack deployed на VDS:**
|
||||||
|
- `/opt/stacks/storage/minio-imgproxy/docker-compose.yml` — 3 сервиса: `minio`, `imgproxy`, `imgproxy-nginx`.
|
||||||
|
- `minio` — `minio/minio:latest`, bind `./data:/data`, env `MINIO_ROOT_USER`/`MINIO_ROOT_PASSWORD` из `pass show minio-vds/root-creds`.
|
||||||
|
- Networks `proxy` (для traefik) + `shared-dbs` (для inter-container).
|
||||||
|
2. **Traefik routing:**
|
||||||
|
- `minio.vds.kzntsv.site` → HTTPS → minio:9000 (S3 API).
|
||||||
|
- `minio-console.vds.kzntsv.site` → HTTPS → minio:9001 (web UI, basicAuth optional).
|
||||||
|
- LE certs auto-issued через existing acme.json.
|
||||||
|
3. **Data migration:**
|
||||||
|
- Snapshot: `tar czf minio-bind-snapshot-$(date +%Y%m%d).tar.gz C:\Users\vitya\projects\docker\diskstation\minio\data` (3 GB → ~3 GB compressed) — rollback insurance.
|
||||||
|
- Поднять new MinIO **пустой** на VDS, создать matching buckets.
|
||||||
|
- `mc alias set old http://localhost:9000 …` + `mc alias set new https://minio.vds.kzntsv.site …`.
|
||||||
|
- `mc mirror --preserve old/<bucket> new/<bucket>` для каждого bucket.
|
||||||
|
- **Verify:** `mc ls --recursive old/<b>` vs `mc ls --recursive new/<b>` — diff пустой, total size match (±0 bytes).
|
||||||
|
- **Fallback при ошибках mc mirror:** `aws s3 sync s3://old/<b> s3://new/<b> --endpoint-url=…`.
|
||||||
|
4. **imgproxy + imgproxy-nginx подняты на VDS:**
|
||||||
|
- `IMGPROXY_S3_ENDPOINT=http://minio:9000`, `IMGPROXY_USE_S3=true`, `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY` из MinIO creds.
|
||||||
|
- `imgproxy-nginx` reverse-proxy с caching layer перед imgproxy.
|
||||||
|
- Сохранить cache path/sizing config с source (`/var/cache/nginx/imgproxy` или эквивалент).
|
||||||
|
5. **CMS endpoints repointed:**
|
||||||
|
- MinIO endpoint в CMS config → `minio.vds.kzntsv.site` (или прямо `http://minio:9000` если CMS migrate тоже на VDS позже).
|
||||||
|
- imgproxy URL pattern в CMS templates → новый адрес.
|
||||||
|
- Smoke: 8 sites загружают images через imgproxy (admin assets UI + клиентские thumbnails).
|
||||||
|
6. **Backup pipeline на VDS расширен** (`/opt/stacks/backup/scripts/run.sh`):
|
||||||
|
- `minio_mirror` ежедневно — либо `mc mirror local→backup-bucket-on-kreknin`, либо `rsync /opt/stacks/storage/minio-imgproxy/data → kreknin`. Recommend rsync — проще и hardlink-friendly.
|
||||||
|
7. **ntfy push verified** для расширенного pipeline (включает MinIO size/duration).
|
||||||
|
8. **Source windows-host:** после 48ч uptime на VDS — `docker stop minio imgproxy imgproxy-nginx`, через неделю `docker rm + docker volume rm` (minio bind-dir — оставить tar snapshot ещё месяц).
|
||||||
|
9. **Documented** в [[../.wiki/concepts/minio-imgproxy-on-vds]] (создать): architecture, MinIO upgrade notes (что сломалось при `mc mirror` если что-то), rollback recipe, migration runbook.
|
||||||
|
|
||||||
|
## Open questions
|
||||||
|
- [ ] **DNS A-records** `minio.vds.kzntsv.site` + `minio-console.vds.kzntsv.site` → VDS IP — REGRU API или manual?
|
||||||
|
- [ ] **MinIO upgrade compat** — есть ли в bucket'ах metadata format'ы которые новый MinIO не читает? `mc admin info` на source + dry-run `mc mirror --dry-run` для оценки. Если ругается → план B: запустить **тот же** старый MinIO image на VDS, мигрировать as-is, upgrade отдельной таской позже.
|
||||||
|
- [ ] **imgproxy version** — текущий `darthsim/imgproxy` (no tag = latest на момент pull). Upgrade сразу или сохранить same digest? Рекомендую pin digest sources → use same on VDS, separate upgrade task.
|
||||||
|
- [ ] **nginx cache size on VDS** — сколько диска готов выделить под `imgproxy-nginx` cache? Текущее consumption на windows — проверить через `du -sh` к bind-mount.
|
||||||
|
|
||||||
|
## Risks
|
||||||
|
- **MinIO format compat (5-year gap):** RELEASE.2020-07-13 → 2025+. `xl.meta` format и erasure-coding mode менялись. `mc mirror` обычно работает (read API stable), но edge-cases возможны. **Mitigation:** snapshot bind-mount + dry-run mirror + fallback aws-s3-sync.
|
||||||
|
- **imgproxy ENV vars** могли переименоваться между версиями (IMGPROXY_S3_* prefix vs IMGPROXY_OBJECT_STORAGE_*). Проверить current container env (`docker inspect imgproxy`) и сопоставить с current imgproxy docs.
|
||||||
|
- **External URL change** — клиентские sites которые ссылаются на `localhost:8788/...` или hardcoded image URLs ломаются. Audit обязателен (`grep -r '8788\|localhost:9000' web.config + appsettings`).
|
||||||
|
- **VDS RAM:** minio idle ~50 MB, imgproxy ~30 MB. Negligible.
|
||||||
|
- **VDS Disk:** ~3 GB MinIO + nginx cache (5-10 GB?) + imgproxy temp. Total ~15 GB. **Проверить `df -h /opt/stacks` перед стартом.**
|
||||||
|
- **DNS propagation:** A-record нужно ставить минимум за 1-2ч до cutover (TTL 300 sec default REGRU).
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
- **Зависит от:** `mssql-vds-migration` (нет — независимы).
|
||||||
|
- **Atomic revert (full):** revert CMS endpoints → windows-host MinIO; на VDS — `docker compose down -v` для minio-imgproxy stack; удалить minio nogi из `run.sh`; remove traefik routes. Snapshot tar — rollback source при необходимости.
|
||||||
77
.tasks/mssql-vds-migration.md
Normal file
77
.tasks/mssql-vds-migration.md
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
# mssql-vds-migration
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
Перенести MSSQL контейнер с [[../entities/windows-recovery-host]] на [[../entities/vds-kzntsv]] (`/opt/stacks/databases/mssql/`), Express Edition для прода, доступ снаружи через `mssql.kzntsv.site:1433` (traefik TCP passthrough), интеграция в существующий `vds-backup-rsync-kreknin` pipeline.
|
||||||
|
|
||||||
|
Это **MSSQL-only половина** umbrella'ы `mssql-minio-migration-to-vds` (декомпозирована 2026-05-22). Вторая половина — `minio-imgproxy-vds-migration`.
|
||||||
|
|
||||||
|
## Key files / refs
|
||||||
|
- **Source:** docker container `mssql` на windows-recovery-host, image `mcr.microsoft.com/mssql/server:2019-latest`, volume `mssql_mssql_data` (26.6 GB total, real data ~2.4 GB, остальное .ldf logs).
|
||||||
|
- **Source DBs** (verified via `docker exec mssql ls /var/opt/mssql/data/`, 2026-05-22):
|
||||||
|
- `MoreThenCms.mdf` 867 MB + log 9.9 GB
|
||||||
|
- `StayerCalculator.mdf` 504 MB + log 1.2 GB
|
||||||
|
- `StayerPrice.mdf` 38 MB + log 215 MB
|
||||||
|
- `TireService.mdf` 8 MB + log 8 MB
|
||||||
|
- `stostayer.mdf` 968 MB + log 264 MB
|
||||||
|
- **Max .mdf 968 MB < 10 GB Express limit ✓ all fit**
|
||||||
|
- **Target:** `/opt/stacks/databases/mssql/{data,docker-compose.yml,.env}` на VDS, паттерн как у postgres (`/opt/stacks/databases/postgres/data` bind, network `proxy` + `shared-dbs`).
|
||||||
|
- **Image:** `mcr.microsoft.com/mssql/server:2022-latest` Express Edition (`MSSQL_PID=Express`).
|
||||||
|
- **CMS connection strings:** `Data Source=localhost,1433` → `Data Source=mssql.kzntsv.site,1433` в IIS web.config / appsettings.
|
||||||
|
- **TLS:** self-signed, traefik raw-TCP passthrough — pattern [[../.wiki/concepts/db-tls-self-signed-via-traefik-raw-tcp]] + [[../.wiki/concepts/traefik-tcp-passthrough-vs-starttls]].
|
||||||
|
- **Backup pipeline:** `/opt/stacks/backup/scripts/run.sh` на VDS — добавить новые ноги (см. acceptance 6).
|
||||||
|
|
||||||
|
## Decisions
|
||||||
|
- **Edition: Express** (user 2026-05-22). Max DB size 10 GB соблюдён всеми текущими базами. RAM cap Express = 1.4 GB built-in. Дополнительно `MSSQL_MEMORY_LIMIT_MB=2048` (user-confirmed), но Express всё равно сам зажмёт до 1410.
|
||||||
|
- **Method: BACKUP DATABASE … WITH COMPRESSION, COPY_ONLY** → scp `.bak` → RESTORE на VDS. Не detach/attach — кросс-edition (Developer → Express) supported только через backup/restore. Compression ≈ 80% reduction, ожидаемый transfer ~500 MB.
|
||||||
|
- **Pre-cutover SHRINKFILE на .ldf** — срежет 12 GB logs до минимума (не для transfer — для cleanup source перед миграцией; transfer идёт через .bak, который и так не включает inactive log space).
|
||||||
|
- **Hostname: `mssql.kzntsv.site`** (не `mssql.vds.kzntsv.site` — user decision 2026-05-22). DNS A-record указать на VDS IP.
|
||||||
|
|
||||||
|
## Acceptance
|
||||||
|
1. **Pre-cutover на source** (windows-host):
|
||||||
|
- `BACKUP LOG <db> WITH TRUNCATE_ONLY` + `CHECKPOINT` + `DBCC SHRINKFILE` для .ldf всех 5 prod DBs.
|
||||||
|
- Verify `du -sh /var/opt/mssql/data/*_log.ldf` → каждый < 100 MB.
|
||||||
|
- **WARNING:** SHRINKFILE с TRUNCATE_ONLY ломает log-chain → no point-in-time restore до следующего FULL backup. Делается **только** в migration window, новый FULL снимается сразу после RESTORE на VDS.
|
||||||
|
2. **MSSQL container на VDS** запущен:
|
||||||
|
- `mcr.microsoft.com/mssql/server:2022-latest`, `ACCEPT_EULA=Y`, `MSSQL_PID=Express`, `MSSQL_MEMORY_LIMIT_MB=2048`, `SA_PASSWORD` из `pass show mssql-vds/sa-password` (новый pass entry).
|
||||||
|
- Volume bind `/opt/stacks/databases/mssql/data:/var/opt/mssql:rw`.
|
||||||
|
- Networks `proxy` + `shared-dbs`. Traefik labels TCP entrypoint `mssql` :1433 → HostSNI(`*`).
|
||||||
|
3. **Traefik static config** (`/opt/stacks/proxy/traefik/traefik.yml`):
|
||||||
|
```yaml
|
||||||
|
entryPoints:
|
||||||
|
mssql:
|
||||||
|
address: ":1433"
|
||||||
|
```
|
||||||
|
+ ufw allow 1433/tcp.
|
||||||
|
4. **5 prod DBs restored** на VDS:
|
||||||
|
- `BACKUP DATABASE … WITH COMPRESSION, COPY_ONLY` на source → 5 `.bak` файлов.
|
||||||
|
- scp → `/opt/stacks/databases/mssql/data/backups/` на VDS.
|
||||||
|
- `RESTORE DATABASE … FROM DISK='/var/opt/mssql/backups/<db>.bak' WITH MOVE`.
|
||||||
|
- Verify `SELECT name, state_desc FROM sys.databases` → все 5 ONLINE, `DBCC CHECKDB('<db>')` → 0 errors на каждой.
|
||||||
|
5. **CMS connection strings updated** в web.config (или эквиваленте), 8 sites smoke:
|
||||||
|
- 200 OK + asset loading + admin/assets/getList (известный hot-path).
|
||||||
|
- **Pre-cutover benchmark обязателен** — admin assets UI / search / catalogs latency измерены до и после, **degradation <2x** target. Если worse — discuss перед commit'ом cutover (10-30ms WAN vs localhost).
|
||||||
|
6. **Backup pipeline на VDS расширен** (`/opt/stacks/backup/scripts/run.sh`):
|
||||||
|
- `mssql_dump_full` ежедневно (BACKUP DATABASE WITH COMPRESSION для каждой DB → tar.gz → rsync nightly).
|
||||||
|
- `mssql_tx_log_backup` ежечасно (BACKUP LOG для каждой DB через `docker exec mssql /opt/mssql-tools/bin/sqlcmd …`) → rsync hourly. **Достигает target RPO 1ч.**
|
||||||
|
7. **ntfy push verified** для расширенного pipeline (включает MSSQL dump size/duration).
|
||||||
|
8. **Source windows-host MSSQL** — после 48ч uptime на VDS: stop container (read-only fallback пропустить — pass), через неделю — `docker rm + docker volume rm mssql_mssql_data`.
|
||||||
|
9. **Documented** в [[../.wiki/concepts/mssql-on-vds]] (создать): architecture, rollback recipe (revert connection strings + start windows-host MSSQL container), migration runbook.
|
||||||
|
|
||||||
|
## Open questions
|
||||||
|
- [ ] **DNS A-record `mssql.kzntsv.site` → VDS IP** (89.253.255.94) — сделать через REGRU API или manual?
|
||||||
|
- [ ] **Hermes service на windows-host** — зависит от local MSSQL? Если да — мигрируется заодно или ломается. См. [[../.wiki/entities/vds-kzntsv]] Open issues.
|
||||||
|
- [ ] **CMS connection-string location** — web.config? appsettings? hardcoded в DLL? Если hardcoded — нужен rebuild (build env вопрос). См. note в [[../.wiki/concepts/cms-admin-assets-root-folder-seed]] §"Долгосрочный TODO".
|
||||||
|
|
||||||
|
## Risks
|
||||||
|
- **WAN latency IIS→MSSQL:** 10-30ms vs localhost. Большинство CMS-операций batchey, не latency-sensitive. **Pre-cutover benchmark обязателен** (acceptance 5).
|
||||||
|
- **Express Edition limits:** 10 GB/DB, 1.4 GB RAM, 1 socket / 4 cores. Max .mdf сейчас 968 MB — запас 10x. Если `stostayer` начнёт расти — early warning через monitoring (separate task).
|
||||||
|
- **MSSQL Linux compat:** некоторые edge-case T-SQL отличаются (CLR, FileStream, full-text). Smoke обязателен — `EXEC sp_helpdb` + проверить нет ли CLR assemblies / FileStream filegroups в prod DBs.
|
||||||
|
- **TLS overhead:** raw-TCP через traefik adds <1ms — negligible.
|
||||||
|
- **VDS RAM tight:** owncloud `anon` 282 MB + gitea 834 MB + verdaccio 226 MB + DBs 285 MB + traefik 52 MB + redis 6 MB = ~1.7 GB реально используется (page-cache reclaimable). MSSQL 2 GB влезает с запасом 4 GB до OOM.
|
||||||
|
- **Disk free на VDS не проверен** (ops-mcp read-only docker). Нужно ~3 GB MSSQL restored + ~5 GB free для backup'ов. **Проверить `df -h /opt/stacks` ssh'ем перед стартом.**
|
||||||
|
- **Cutover rollback:** revert возможен только если windows-host MSSQL container оставлен running (read-only желательно но не критично) 48ч после cutover. Acceptance 8 это закладывает.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
- **Зависит от:** `minio-imgproxy-vds-migration` (нет — независимы).
|
||||||
|
- **Зависимая follow-up:** списать `cms-stopgap-backup-daily` cron после успешного first VDS backup-pipeline run.
|
||||||
|
- **Atomic revert (full):** revert CMS web.config → windows-host MSSQL; восстановить cms-stopgap-backup-daily cron; на VDS — `docker compose down -v` для mssql stack; удалить mssql ноги из `run.sh`; remove traefik mssql entrypoint; ufw deny 1433/tcp.
|
||||||
Reference in New Issue
Block a user