Files
netrunner-data/scripts/migrate-vaultwarden.md
T
nineap 049d38a2b9 Vaultwarden делит один Postgres-процесс с netrunner-backend
Убирает собственный контейнер db — вместо своего Postgres подключается
внешней сетью (netrunner_grid, external: true) к netrunner-db из
netrunner-backend/docker-compose.prod.yml, в отдельной базе/юзере
(VW_DB_*, был DB_*). Экономит ресурсы на VPS, где раньше крутились бы
два отдельных Postgres-процесса. Добавляет пошаговый ранбук переноса
существующих данных со старого SQLite-инстанса (scripts/migrate-vaultwarden.md,
через checkpoint WAL + pgloader data-only на уже созданную diesel-схему).

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

148 lines
8.4 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)
Задеплоить (или обновить) прод `netrunner-backend` **первым** — Vaultwarden
теперь не поднимает свой Postgres, а подключается к тому же контейнеру
`netrunner-db` и сети `netrunner_grid`, которые создаёт
`netrunner-backend/docker-compose.prod.yml`. Пока backend не поднят на этом
VPS — `docker compose up` для vaultwarden ниже упадёт с "network netrunner_grid
not found".
Затем создать отдельную базу и роль для Vaultwarden в этом общем Postgres
(не переиспользовать логин backend'а):
```bash
# На новом VPS, после того как netrunner-backend/docker-compose.prod.yml поднят
docker exec -it netrunner-db psql -U "$DB_USER" -d postgres -c \
"CREATE ROLE vaultwarden WITH LOGIN PASSWORD 'СЮДА_ТОТ_ЖЕ_ПАРОЛЬ_ЧТО_В_VW_DB_PASSWORD';"
docker exec -it netrunner-db psql -U "$DB_USER" -d postgres -c \
"CREATE DATABASE vaultwarden OWNER vaultwarden;"
```
(`$DB_USER` — существующий админ-юзер backend-Postgres, из его `.env`.)
## Фаза 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 netrunner_grid \
-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@netrunner-db:5432/vaultwarden
```
Проверить, что 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"` для этой таблицы (медленнее, но
проще диагностировать построчно). Не обязательно решать это заранее — сначала
просто прогнать команду выше и смотреть на реальный лог ошибок.