Self-hosting a password manager sounds like a brilliant idea right up until you think about what happens if it breaks. Lose your media server and you re-download some films. Lose your password vault and you’re locked out of everything.
So this post is half “how to set up Vaultwarden” and half “how to make sure you never lose it”.
What is Vaultwarden?
Vaultwarden is a lightweight, unofficial server that speaks the Bitwarden protocol. That means you use the official Bitwarden apps and browser extensions, but your encrypted vault lives on your own hardware instead of Bitwarden’s servers. It’s written in Rust and uses very little memory, so it runs happily on a small VM.
The compose file
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: unless-stopped
environment:
DOMAIN: "https://vault.example.com"
SIGNUPS_ALLOWED: "false"
ADMIN_TOKEN: "${VW_ADMIN_TOKEN}" # argon2 hash, see below
volumes:
- ./data:/data
ports:
- "8081:80"
A few settings matter here:
SIGNUPS_ALLOWED=false: create your own account first, then turn this off. Otherwise anyone who can reach the page can make an account on your server.ADMIN_TOKEN: enables the/adminpage. Don’t store it in plain text. Generate a hashed version with:docker exec -it vaultwarden /vaultwarden hashand paste the resulting
$argon2id$...string into your.envfile. If you put it straight into the compose file, double every$to$$.DOMAIN: set this to the exact HTTPS address you’ll use.
HTTPS isn’t optional
The Bitwarden web vault uses browser crypto APIs that only work over HTTPS. Visit it over plain HTTP and it simply won’t let you log in. I already had a reverse proxy with a wildcard certificate (see my last post), so this was one more proxy host pointing at the container.
Should it be on the internet?
My recommendation is no, not directly. The Bitwarden apps cache your vault offline, so you can still read your passwords when you’re away from home. You only need to reach the server to sync changes. A VPN like Tailscale (next-but-one post) gives you that without exposing the login page to the whole internet.
If you do expose it, put it behind Cloudflare, enable two-factor on your account, and keep the container updated.
Backups: the important bit
Everything Vaultwarden needs lives in the /data folder:
| File/folder | What it is |
|---|---|
db.sqlite3 | Your encrypted vault data |
attachments/ | File attachments |
sends/ | Bitwarden Send files |
rsa_key* | Keys used to sign login tokens |
config.json | Settings changed from the admin page |
Don’t just copy db.sqlite3 while the container is running. You can catch it mid-write and end up with a corrupt backup. Use SQLite’s own backup command, which takes a consistent snapshot:
#!/bin/bash
set -e
SRC=/opt/vaultwarden/data
DEST=/mnt/backup/vaultwarden/$(date +%F)
mkdir -p "$DEST"
sqlite3 "$SRC/db.sqlite3" ".backup '$DEST/db.sqlite3'"
cp -r "$SRC/attachments" "$SRC/sends" "$DEST/" 2>/dev/null || true
cp "$SRC"/rsa_key* "$SRC/config.json" "$DEST/" 2>/dev/null || true
# keep 30 days
find /mnt/backup/vaultwarden -maxdepth 1 -type d -mtime +30 -exec rm -rf {} +
I run this nightly with cron. The destination is a share on my NAS mounted over NFS, so the backups live on a different machine from the VM.
Tip: Install
sqlite3on the VM (sudo apt install sqlite3) first. Without it the script stops at the first step, and because cron runs quietly in the background, you’ll think you have backups when you don’t. Check the backup folder after the first night.
Test the restore
A backup you’ve never restored is a hope, not a backup. Once a month (or at least once), I:
- Spin up a throwaway Vaultwarden container.
- Point it at a copy of last night’s backup.
- Log in and check my entries are there.
It takes five minutes and it’s the only way to know the backups work.
Belt and braces
Even with nightly backups, I keep one more safety net: an encrypted export from the Bitwarden app (Settings → Export vault → encrypted JSON), stored offline. If the server, the NAS and the house all have a bad day at once, I can still import it into any Bitwarden-compatible service.
Was it worth it?
Yes. It’s fast, it works with every Bitwarden app, and I know exactly where my data is. Just don’t skip the backups.


