Run your own password manager with Vaultwarden
Vaultwarden is a lightweight server that speaks the Bitwarden protocol. You keep using the official Bitwarden apps and browser extensions, but the vault lives on your own VPS. It runs happily in very little RAM, which makes it one of the best first things to self-host.
This builds on the Docker and Caddy setup. If you haven't got that running yet, start there. Bitwarden clients refuse to work without HTTPS, and Caddy is the easy way to get it.
Add it to your compose file
vaultwarden:
image: vaultwarden/server:latest
restart: unless-stopped
environment:
DOMAIN: "https://vault.example.com"
SIGNUPS_ALLOWED: "true"
volumes:
- vaultwarden:/data
And add vaultwarden: under the volumes: section at the bottom of the file.
Add it to Caddy
vault.example.com {
reverse_proxy vaultwarden:80
}
docker compose up -d docker compose exec -w /etc/caddy caddy caddy reload
Point a DNS record for vault.example.com at your server first, or Caddy can't get a certificate.
Create your account, then lock the door
Open https://vault.example.com, create your account, and log in once to check it works. Then turn signups off. Otherwise anyone who finds the URL can make an account on your server:
SIGNUPS_ALLOWED: "false"
docker compose up -d
Need to add family members later? Flip it back to true for five minutes, or set up the admin page and send invites from there.
Connect the apps
In any Bitwarden app or browser extension, look for the server or region selector on the login screen. Pick self-hosted and enter https://vault.example.com. Everything else works as normal: autofill, sync between devices, the lot.
The admin page (optional)
Vaultwarden has an admin panel at /admin. It stays switched off until you set a token. If you want it, generate a hashed token instead of putting a plain password in your compose file:
docker run --rm -it vaultwarden/server /vaultwarden hash
Put the output in ADMIN_TOKEN. In a compose file, every $ in the hash has to be written as $$, or Compose will try to read it as a variable and mangle it.
Better still, only expose it through a WireGuard tunnel.
Back it up
Your whole vault is a SQLite database in the vaultwarden volume, plus a few attachment files. If this server dies without a backup, every password goes with it. Set up restic backups before you move your real passwords in, and keep an export of your vault somewhere offline as well.