Keep sanitized Compose sources in-repo with a confirmation-gated Ansible playbook, add repo-wide validation, tighten runbook ownership/STOP/review metadata, and archive stale research docs. Co-authored-by: Cursor <cursoragent@cursor.com>
61 lines
2.9 KiB
Markdown
61 lines
2.9 KiB
Markdown
# Runbook: Vaultwarden SQLite → Postgres (us2)
|
|
|
|
## Purpose
|
|
|
|
Replay checklist for the exceptional SQLite→Postgres migration on us2.
|
|
|
|
## Scope
|
|
|
|
- Applicable: [us2.wsvc.info](../hosts/us2.wsvc.info.md), `/opt/vaultwarden`.
|
|
- Not applicable: routine reconcile — this is destructive and intentionally not automated.
|
|
|
|
## Ownership
|
|
|
|
- Owner: personal ops (Windy)
|
|
- Last reviewed: 2026-08-17
|
|
- Related systems: us2.wsvc.info (`/opt/vaultwarden`)
|
|
|
|
## Safety
|
|
|
|
- Destructive: requires explicit approval; confirm backups exist before starting.
|
|
- Do not commit `.env` or password-bearing files to git.
|
|
- If any step diverges from this checklist, `STOP` and report.
|
|
|
|
Target: [us2.wsvc.info](../hosts/us2.wsvc.info.md)
|
|
Upstream: [Using the PostgreSQL Backend](https://github.com/dani-garcia/vaultwarden/wiki/Using-the-PostgreSQL-Backend) · [docs/vaultwarden-upstream.md](../docs/vaultwarden-upstream.md)
|
|
|
|
**Done on 2026-08-01** for this host. Keep this as the replay checklist. This
|
|
is an exceptional, destructive migration procedure: it is intentionally not
|
|
automated by the routine Ansible reconciliation playbook.
|
|
|
|
## Summary of what we did
|
|
|
|
1. Backup `vw-data` + `.env` → `backups/pre-pg-migrate-<timestamp>/`
|
|
2. Baseline counts from SQLite (then: users=1, ciphers=1327)
|
|
3. Drop/recreate empty Postgres DB; pin image `vaultwarden/server:1.37.1`
|
|
4. Set compose `DATABASE_URL=postgresql://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}`
|
|
5. Start VW once → diesel schema → stop
|
|
6. `pgloader` **data only** (exclude `__diesel_schema_migrations`) with CAST bigint→integer
|
|
7. Remaining intentional bigints: `attachments.file_size`, `twofactor.last_used`, `twofactor_duo_ctx.exp`
|
|
8. Align `config.json` SMTP **587/starttls**, `ip_header=X-Forwarded-For`, `DOMAIN` without trailing slash
|
|
9. Rotate `DB_PASS` / `PGWEB_PASS`; `pgweb` behind compose `profiles: [debug]`
|
|
10. Move live sqlite file to `backups/sqlite-cold/` (cold only)
|
|
11. After VW recreate, **restart Traefik** so Docker provider picks up the router
|
|
|
|
## Critical pitfalls
|
|
|
|
- `config.json` overrides `.env` (admin wins). Fix SMTP there or via `/admin`.
|
|
- SMTP password drift: if `.env` AUTH works but VW mail fails with `535`, sync `vw-data/config.json` (+ `.smtp-credentials`) to the mailbox password — do not assume env alone is enough.
|
|
- From this network, **mx2:465 times out**; use **587 + starttls**.
|
|
- After recreating `vaultwarden`, Traefik may 404 until `docker restart traefik`.
|
|
- pgloader needs a **writable** directory for the sqlite file (CANTOPEN if mount is awkward).
|
|
- After pgloader, wrong integer types → silent “wrong password”; see [Discussion #7134](https://github.com/dani-garcia/vaultwarden/discussions/7134).
|
|
- Do not commit `.env` or load files with passwords into git.
|
|
|
|
## Rollback
|
|
|
|
1. `docker compose stop vaultwarden`
|
|
2. Restore `vw-data` from `backups/pre-pg-migrate-*` (including sqlite)
|
|
3. Remove `DATABASE_URL` from compose `environment`
|
|
4. `docker compose up -d vaultwarden` && `docker restart traefik`
|