Vaultwarden is an unofficial, lightweight Bitwarden-compatible server written in Rust. It works with all official Bitwarden clients (browser extensions, mobile, desktop, CLI) but runs in a fraction of the resources. Self-hosting your password manager means your vault never leaves infrastructure you control.
Because this is a *password vault*, security and durability are non-negotiable. This guide deploys Vaultwarden with the hardening it deserves.
Critical principles before you start
- 1Your data must persist. A password vault on an ephemeral disk that disappears on redeploy is a catastrophe. Persistent storage is mandatory.
- 2HTTPS is mandatory. Bitwarden clients refuse non-HTTPS connections for good reason. TLS is required, not optional.
- 3Back up religiously. A lost vault means lost passwords with no recovery.
- 4Lock down signups. An open instance lets strangers register accounts on your server.
Step 1: Deploy the container with persistent storage
Vaultwarden uses an embedded SQLite database by default (or PostgreSQL/MySQL for larger setups), plus attachment and key files — all under /data. This directory must be on a persistent volume.
FROM vaultwarden/server:latest
# Serves on port 80Pin a version tag in production.
- 1Push the repo (or reference
vaultwarden/server) to GitHub. - 2Create a container app on [PandaStack](https://dashboard.pandastack.io).
- 3Attach a persistent volume mounted at
/data. This is the single most important step. - 4Expose port
80. - 5Add a custom domain — SSL is issued automatically (this satisfies the HTTPS requirement).
Step 2: Use a real database for teams (optional but recommended)
SQLite on a single volume is fine for a personal or small-family vault. For an organization, point Vaultwarden at a managed PostgreSQL for better concurrency and easier backups:
DATABASE_URL=postgresql://<user>:<password>@<host>:5432/vaultwardenOn PandaStack, link a managed PostgreSQL and the connection is injected — Vaultwarden picks up DATABASE_URL directly.
Step 3: Lock down configuration
Set these environment variables to harden the instance:
DOMAIN=https://vault.example.com # must match your real HTTPS domain
SIGNUPS_ALLOWED=false # disable open registration
INVITATIONS_ALLOWED=true # invite users instead
ADMIN_TOKEN=<argon2-hash-of-a-strong-token>
SIGNUPS_VERIFY=true # require email verificationKey points:
SIGNUPS_ALLOWED=falseafter you've created your account(s). Otherwise anyone who finds your URL can register.ADMIN_TOKENprotects the/adminpanel. Modern Vaultwarden expects an Argon2 hash of the token (generate it, store the hash, keep the plaintext in your own password manager).DOMAINmust exactly match your HTTPS URL or features like WebAuthn break.
Step 4: Configure SMTP for invitations and 2FA email
To invite users and send email-based features, configure SMTP:
SMTP_HOST=smtp.your-provider.com
SMTP_PORT=587
SMTP_SECURITY=starttls
SMTP_USERNAME=<user>
SMTP_PASSWORD=<password>
SMTP_FROM=vault@example.comStep 5: Create your account and disable signups
- 1With
SIGNUPS_ALLOWED=truetemporarily, visit your domain and register your account. - 2Set a strong master password — this encrypts your entire vault and cannot be recovered if lost.
- 3Set
SIGNUPS_ALLOWED=falseand redeploy. - 4Invite any additional users via the admin panel from then on.
Step 6: Enable two-factor auth
In the web vault, enable 2FA on every account (TOTP at minimum, WebAuthn/passkeys if possible). A self-hosted vault is a high-value target; defense in depth matters.
Step 7: Back up — and test the restore
This is the part people skip until disaster strikes. Back up:
- The
/datavolume (or the managed PostgreSQL) — contains the encrypted vault. - Specifically the
rsa_keyfiles under/datafor SQLite setups — needed to decrypt.
With managed PostgreSQL, scheduled backups cover the database automatically. For the SQLite + volume setup, schedule a periodic export. Then actually test a restore — an untested backup is a hope, not a plan.
| Setup | Backup strategy |
|---|---|
| SQLite + volume | Scheduled volume snapshot / /data export, store offsite |
| Managed PostgreSQL | Scheduled DB backups + volume snapshot for attachments/keys |
Vaultwarden vs. official Bitwarden self-hosted
Official Bitwarden's self-hosted server is fully supported by the company and includes enterprise features, but it's heavier (multiple containers, more resources). Vaultwarden is community-maintained, far lighter, and client-compatible — ideal for individuals and small teams. For large enterprises wanting vendor support, official Bitwarden may be the better fit. Both are legitimate; choose by scale and support needs.
References
- [Vaultwarden wiki](https://github.com/dani-garcia/vaultwarden/wiki)
- [Vaultwarden configuration overview](https://github.com/dani-garcia/vaultwarden/wiki/Configuration-overview)
- [Vaultwarden backups](https://github.com/dani-garcia/vaultwarden/wiki/Backing-up-your-vault)
- [Bitwarden security whitepaper](https://bitwarden.com/help/bitwarden-security-white-paper/)
---
A self-hosted vault is only as good as its persistence and backups — and that's exactly where PandaStack helps: persistent volumes for /data, managed PostgreSQL with scheduled backups, and automatic SSL to satisfy Bitwarden's HTTPS requirement. Just remember to disable open signups and test your restores. Get started at [dashboard.pandastack.io](https://dashboard.pandastack.io).