Test Restore Vaultwarden — runbook (VAULT-02)¶
Цель: проверить что GPG-архив Vaultwarden действительно можно расшифровать и развернуть в рабочий инстанс. Скрипт бэкапа может работать, а restore — нет. Раз в квартал прогоняем и убеждаемся.
Что тестируем:
1. GPG-пароль из бумажного сейфа корректный.
2. Архив распакован без потерь.
3. rsa_key.pem + db.sqlite3 совместимы (не битые).
4. Vaultwarden запускается на восстановленных данных.
5. Логин под нашим master-паролем работает (пароль хранится в голове/сейфе).
Периодичность: раз в 90 дней. Календарное напоминание в LeaderTask или scheduled cron в Perplexity (см. финал).
Требования¶
- Ragserver
192.168.1.200, свободных ~500 MB - Docker установлен (проверить:
docker --version) - Не мешаем production Vaultwarden на VPS — работаем на новом порту 8223
Шаг 1 · Взять свежий бэкап¶
Из off-site (ragserver, VAULT-01):
# На ragserver, от oswold:
cd /home/oswold/backups/vaultwarden
ls -lh *.gpg | tail -3
# Копируем самый свежий:
LATEST=$(ls -t *.gpg | head -1)
echo "Тестируем: $LATEST"
Из VPS (fallback, если ragserver ещё не настроен):
# С VPS скачиваем локально на ragserver:
scp root@46.17.99.183:/opt/vaultwarden/backups/vaultwarden-backup-*.gpg /tmp/vw-restore/
Шаг 2 · Подготовить изолированное окружение¶
# На ragserver:
sudo mkdir -p /opt/vaultwarden-restore-test
cd /opt/vaultwarden-restore-test
sudo mkdir -p data
sudo chown -R oswold:oswold /opt/vaultwarden-restore-test
Шаг 3 · Расшифровать GPG-архив¶
GPG-пароль: возьми с бумаги в сейфе (не из Vaultwarden — если восстанавливаем именно Vaultwarden, то он недоступен).
cd /opt/vaultwarden-restore-test
cp /home/oswold/backups/vaultwarden/$LATEST ./
gpg --output vw-restore.tar.gz --decrypt "$LATEST"
# GPG спросит пароль → вводишь тот что на бумаге
# Ожидание: gpg: encrypted with 1 passphrase (или AES256)
ls -lh vw-restore.tar.gz
Если GPG-пароль неверный → КРИТИЧЕСКИ ВАЖНО — задокументируй в TODO как приоритет 1, потому что бэкапы бесполезны.
Шаг 4 · Распаковать¶
tar -tzf vw-restore.tar.gz | head -20
# Ожидание: список файлов внутри staging-каталога:
# tmp/vw_staging_2026-08-XX_HHMMSS/db.sqlite3
# tmp/vw_staging_.../rsa_key.pem
# tmp/vw_staging_.../attachments/
# ...
tar -xzf vw-restore.tar.gz -C ./
# Найти staging-папку (имя зависит от даты бэкапа):
STAGING=$(find . -type d -name "vw_staging_*" | head -1)
echo "Staging: $STAGING"
ls -la "$STAGING"
Проверь наличие критичных файлов:
for f in db.sqlite3 rsa_key.pem rsa_key.pub.pem env.backup docker-compose.yml; do
if [[ -f "$STAGING/$f" ]]; then
echo "✅ $f — $(stat -c %s "$STAGING/$f") байт"
else
echo "❌ $f — ОТСУТСТВУЕТ (бэкап битый!)"
fi
done
Если что-то отсутствует — бэкап-скрипт на VPS требует правки, стоп-задача.
Шаг 5 · Проверить SQLite целостность¶
Если получаем ошибку (Error: database disk image is malformed и т.п.) — VACUUM INTO в backup.sh сломан, скидываем в TODO как критичное.
Быстрая проверка что там есть данные:
sqlite3 "$STAGING/db.sqlite3" "SELECT COUNT(*) FROM users;"
sqlite3 "$STAGING/db.sqlite3" "SELECT COUNT(*) FROM ciphers;"
# ожидание: >0 в users, >0 в ciphers (сколько у тебя записей)
Шаг 6 · Развернуть тестовый Vaultwarden¶
Копируем данные в изолированную data-папку:
cd /opt/vaultwarden-restore-test
mkdir -p data
cp -r "$STAGING"/* data/
# ⚠️ env.backup не должен попасть в data — он ляжет как .env вне data
mv data/env.backup .env
mv data/docker-compose.yml ./docker-compose-restore.yml
ls -la data/
# Ожидание: db.sqlite3, rsa_key.pem, rsa_key.pub.pem, attachments/, sends/, config.json
Правим docker-compose для теста (порт 8223 вместо 8222):
cat > docker-compose.yml <<'YAML'
services:
vaultwarden-restore:
image: vaultwarden/server:latest
container_name: vaultwarden-restore-test
restart: "no"
env_file: .env
volumes:
- ./data:/data
ports:
# ТОЛЬКО localhost, порт 8223 (не 8222 чтоб не конфликтовать)
- "127.0.0.1:8223:80"
YAML
Правим .env — уберём DOMAIN, SIGNUPS_ALLOWED, чтоб не смущать боевой домен:
# Достаточно чтобы:
grep -E '^(DATABASE_URL|ROCKET|SIGNUPS|DOMAIN|LOG_)' .env
# Если DOMAIN=https://vault.alatyr-service.ru — временно поменяй на http://localhost:8223
sed -i 's|^DOMAIN=.*|DOMAIN=http://localhost:8223|' .env
# И SIGNUPS убеждаемся что false (мы не хотим случайно открыть регистрацию):
grep SIGNUPS_ALLOWED .env
Шаг 7 · Стартуем и проверяем¶
docker compose up -d
sleep 10
docker compose logs --tail=30
# Ожидание в логах:
# Rocket has launched from http://0.0.0.0:80
# Vaultwarden 1.36.x started
Healthcheck из соседнего терминала:
Логин через веб (через SSH-туннель):
# С твоего локального компа:
ssh -L 8223:localhost:8223 oswold@192.168.1.200
# В браузере: http://localhost:8223
# Логин: твоим master-паролем от Vaultwarden
# Ожидание: список твоих записей загружается, содержимое читаемо
Если логин работает и записи открываются → ✅ restore прошёл, бэкапы рабочие.
Шаг 8 · Уборка (обязательно!)¶
cd /opt/vaultwarden-restore-test
docker compose down
sudo rm -rf /opt/vaultwarden-restore-test
# Убедиться что нигде нет незашифрованных данных:
ls /opt/vaultwarden-restore-test 2>/dev/null && echo "ERROR: осталось" || echo "OK: удалено"
Шаг 9 · Записать факт теста¶
В vaultwarden.md обнови секцию "Тест восстановления":
В TODO.md отметь ✅:
Запланируй следующий на +90 дней:
Или scheduled cron в Perplexity: раз в 90 дней напоминание "Прогони restore-test-vaultwarden.md".
Что если restore ПРОВАЛИЛСЯ¶
| Симптом | Диагноз | Действия |
|---|---|---|
| GPG "Bad passphrase" | Пароль на бумаге неверный | 🔴 приоритет 1: найти правильный, обновить сейф |
integrity_check не ok |
VACUUM INTO в backup.sh не работает |
🔴 п1: править backup.sh, тестировать снова |
| Vaultwarden не стартует | Битый rsa_key.pem | 🔴 п1: backup.sh не бэкапит ключи — критично |
| Логин работает, но пусто | БД без данных, attachments/ не сбэкаплен |
🟡 п3: backup.sh не берёт attachments/ |
| Логин не работает | Master-пароль забыт | 🔴 п1: master-пароль пиши на бумагу тоже |
Каждый провал → сразу задача в TODO с приоритетом 1.
Автоматизация напоминаний (опционально)¶
Через pplx-tool schedule_cron — раз в 90 дней:
cron: 0 10 1 */3 *
task: "Напоминание: пришло время test restore Vaultwarden. Запусти restore-test-vaultwarden.md на ragserver."
Первое напоминание — 01.11.2026 в 10:00 MSK.
Автор: агент, 08.08.2026