- 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>
8.2 KiB
8.2 KiB
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, imagemcr.microsoft.com/mssql/server:2019-latest, volumemssql_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.mdf867 MB + log 9.9 GBStayerCalculator.mdf504 MB + log 1.2 GBStayerPrice.mdf38 MB + log 215 MBTireService.mdf8 MB + log 8 MBstostayer.mdf968 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/databind, networkproxy+shared-dbs). - Image:
mcr.microsoft.com/mssql/server:2022-latestExpress 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
- 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.
- 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 entrypointmssql:1433 → HostSNI(*).
- Traefik static config (
/opt/stacks/proxy/traefik/traefik.yml):entryPoints: mssql: address: ":1433"- ufw allow 1433/tcp.
- 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 на каждой.
- 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).
- 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ч.
- ntfy push verified для расширенного pipeline (включает MSSQL dump size/duration).
- Source windows-host MSSQL — после 48ч uptime на VDS: stop container (read-only fallback пропустить — pass), через неделю —
docker rm + docker volume rm mssql_mssql_data. - 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
anon282 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/stacksssh'ем перед стартом. - Cutover rollback: revert возможен только если windows-host MSSQL container оставлен running (read-only желательно но не критично) 48ч после cutover. Acceptance 8 это закладывает.
Notes
- Зависит от:
minio-imgproxy-vds-migration(нет — независимы). - Зависимая follow-up: списать
cms-stopgap-backup-dailycron после успешного 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.