9ca6df3dfc
Раньше предполагалось, что 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>
144 lines
8.5 KiB
Markdown
144 lines
8.5 KiB
Markdown
# Перенос 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"` для этой таблицы (медленнее, но
|
||
проще диагностировать построчно). Не обязательно решать это заранее — сначала
|
||
просто прогнать команду выше и смотреть на реальный лог ошибок.
|