Files
netrunner-data/scripts/migrate-vaultwarden.md
T
nineap 9ca6df3dfc Postgres переезжает сюда физически — backend теперь на отдельном VPS
Раньше предполагалось, что backend и БД живут на одном хосте и делят
Docker-сеть — на деле backend будет на отдельном, ещё не арендованном
VPS, а Postgres стоит здесь же, рядом с Vaultwarden. Возвращает свой
контейнер `db` (общий для обеих баз — vaultwarden создаётся через
POSTGRES_USER/POSTGRES_DB, вторая, для backend, через новый
postgres/init-backend-db.sh), публикует 5432 наружу с hostssl+TLS
(postgres/pg_hba.conf, самоподписанный сертификат генерируется один раз
прямо в deploy.yml). Backup-джоба (pg_dump обеих баз) тоже переехала
сюда из netrunner-backend — дампить логичнее там, где физически лежат
данные.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-09 17:17:05 +07:00

144 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Перенос Vaultwarden со старого VPS на новый (136.244.78.208), SQLite → Postgres
Все команды — ручные, выполняются вами на серверах (у меня нет SSH-доступа ни
к старому, ни к новому VPS). Ниже — точная последовательность без потери
данных. Не удалять старый сервер/старые файлы, пока не пройден пункт
"Проверка" в самом конце.
Старый инстанс живёт на SQLite в WAL-режиме (видно по файлам `db.sqlite3-wal`
и `db.sqlite3-shm` рядом с `db.sqlite3` — это значит часть последних изменений
может ещё не быть слита в основной файл). Поэтому нельзя просто скопировать
`db.sqlite3` в одиночку — копируем директорию `data/` целиком и только после
чистой остановки контейнера.
## Фаза 0 — предварительно, на новом VPS (136.244.78.208)
Postgres теперь физически стоит прямо здесь, в этом репозитории
(`docker-compose.yml`, сервис `db`) — не в netrunner-backend. Задеплоить этот
репозиторий (через CI или руками `docker compose up -d`) — обе базы
(`vaultwarden` и netrunner-backend) создаются автоматически при первой
инициализации кластера: `vaultwarden` через `POSTGRES_USER`/`POSTGRES_DB`,
вторая — через `postgres/init-backend-db.sh` (`BACKEND_DB_USER`/
`BACKEND_DB_NAME`). Ручных `CREATE ROLE`/`CREATE DATABASE` не требуется.
netrunner-backend сам ещё не задеплоен (живёт на отдельном, пока не
арендованном VPS) — это не мешает: Vaultwarden обращается к `db` внутри
локальной Docker-сети этого же compose, backend подключится позже по сети,
когда появится.
## Фаза 1 — на СТАРОМ сервере (текущий Vaultwarden)
```bash
cd ~/vaultwarden-data
# Останавливаем контейнер — чистое закрытие sqlite-соединения (checkpoint
# WAL в основной файл на выходе). НЕ удалять после — только stop.
docker compose stop vaultwarden
# На всякий случай форсируем checkpoint+truncate WAL явно, а не полагаемся
# только на чистое закрытие процессом:
docker run --rm -v "$PWD/data:/data" alpine:3.20 sh -c \
"apk add --no-cache sqlite >/dev/null && sqlite3 /data/db.sqlite3 'PRAGMA wal_checkpoint(TRUNCATE);'"
# Теперь весь ./data — самодостаточный снимок. Архивируем целиком одним
# куском (attachments, rsa_key.pem, db.sqlite3 — всё вместе, не выборочно).
tar czf ~/vaultwarden-data-backup-$(date +%Y%m%d-%H%M%S).tar.gz -C ~/vaultwarden-data data
ls -la ~/vaultwarden-data-backup-*.tar.gz
```
Скопировать архив на новый VPS (с любой машины, у которой есть доступ к
обоим — например, с вашего ноутбука):
```bash
scp root@<СТАРЫЙ_VPS_IP>:~/vaultwarden-data-backup-*.tar.gz .
scp vaultwarden-data-backup-*.tar.gz root@136.244.78.208:~/
```
Старый Vaultwarden пока НЕ запускать обратно — он останется единственным
живым источником правды до подтверждённого успеха миграции (Фаза 4).
## Фаза 2 — распаковка на НОВОМ сервере
```bash
# На новом VPS (136.244.78.208)
mkdir -p ~/netrunner-data
cd ~/netrunner-data
git clone <URL_РЕПО_netrunner-data> . 2>/dev/null || true # если ещё не клонирован
tar xzf ~/vaultwarden-data-backup-*.tar.gz -C ~/netrunner-data
# теперь ~/netrunner-data/data/db.sqlite3 (+ -wal/-shm, rsa_key.pem, ...) на месте
ls -la ~/netrunner-data/data
```
## Фаза 3 — конвертация SQLite → Postgres через pgloader
Сначала дать Vaultwarden создать пустую Postgres-схему (diesel-миграции идут
из самого бинаря при первом старте с `DATABASE_URL=postgresql://...`) —
**НЕ через pgloader**: типы колонок в postgres-схеме vaultwarden подогнаны под
его собственный Rust/diesel-код, автосоздание схемы pgloader'ом из sqlite-типов
даст несовместимую структуру.
```bash
# .env уже должен быть заполнен (VW_DB_USER/VW_DB_PASSWORD/VW_DB_NAME и т.д.)
cd ~/netrunner-data
docker compose up -d vaultwarden
sleep 5
docker compose logs vaultwarden | tail -30 # убедиться что миграции прошли, схема создана
docker compose stop vaultwarden # снова стоп — дальше пишет только pgloader
```
Теперь перелить данные (не схему) из sqlite-файла в уже созданную схему:
```bash
docker run --rm \
--network host \
-v ~/netrunner-data/data:/data \
dimitri/pgloader:latest \
pgloader \
--with "data only" \
--with "disable triggers" \
--with "quote identifiers" \
sqlite:///data/db.sqlite3 \
postgresql://vaultwarden:СЮДА_VW_DB_PASSWORD@localhost:5432/vaultwarden
```
(`--network host` + `localhost:5432` — Postgres на этом же VPS уже публикует
порт наружу, так что localhost работает без разбора имени Docker-сети.)
Проверить, что pgloader завершился без ошибок ("... rows" summary без Errors)
— если есть ошибки по конкретным таблицам, здесь и надо разбираться, ДО того
как запускать vaultwarden поверх.
## Фаза 4 — запуск и проверка
```bash
cd ~/netrunner-data
docker compose up -d vaultwarden
docker compose logs -f vaultwarden # ждём "Rocket has launched" без ошибок БД
```
Затем, ДО переключения DNS на новый IP:
- Зайти по прежнему домену через `/etc/hosts`-подмену (временно указать
`vault.netrunner-vpn.com` на `136.244.78.208` только на своей машине) и
залогиниться существующим аккаунтом — проверить, что все записи/сейфы на
месте, вложения открываются.
- Проверить 2FA/WebAuthn там, где он был настроен — привязан к домену, не к
IP, так что при простой смене DNS (см. ниже) ломаться не должен.
Только после успешного логина и видимых данных:
1. Переключить DNS A-запись `vault.netrunner-vpn.com` на `136.244.78.208`.
2. Подождать TTL, ещё раз проверить логин уже по-настоящему через домен.
3. Только теперь можно выключить (не обязательно сразу удалять) старый
Vaultwarden — оставить его на пару дней выключенным как холодный откат,
прежде чем сносить директорию `~/vaultwarden-data` на старом сервере.
## Если pgloader ругается на конкретную таблицу
Обычно это `twofactor`/`ciphers` из-за BLOB/бинарных полей — можно догнать их
руками через `INSERT INTO ... SELECT` в отдельном скрипте или повторным
прогоном pgloader с `--with "batch rows = 1"` для этой таблицы (медленнее, но
проще диагностировать построчно). Не обязательно решать это заранее — сначала
просто прогнать команду выше и смотреть на реальный лог ошибок.