How to Install Vaultwarden (Self-Hosted Bitwarden Password Manager)

A password manager is the single best thing you can do for your online security, and Vaultwarden lets you host one yourself. It's a lightweight reimplementation of the Bitwarden server, so you use the real Bitwarden apps and browser extensions — polished, audited, on every platform — but your encrypted vault lives on your own server.
Quick reference
| Task | What |
|---|---|
| Folder | ~/docker/vaultwarden/compose.yaml |
| Must have | HTTPS — the apps refuse plain http |
| Admin page | https://vault.example.com/admin (with ADMIN_TOKEN) |
| Sign-ups | SIGNUPS_ALLOWED: "false" once your accounts exist |
| Apps | Bitwarden (iOS, Android, Windows, Mac, every browser) → Self-hosted → your URL |
| Backup | ./data folder, especially db.sqlite3 |
Before you start
The Bitwarden apps only talk to HTTPS. You need a domain name pointing at the server and Nginx with a certificate (tutorials 27 and 28). If you don't want the vault reachable from the internet, use the VPN and an internal name with a certificate from the DNS challenge.
1. The compose file
mkdir -p ~/docker/vaultwarden && cd ~/docker/vaultwarden
nano compose.yaml
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
ports:
- "127.0.0.1:8222:80"
environment:
DOMAIN: https://vault.example.com
SIGNUPS_ALLOWED: "true"
ADMIN_TOKEN: a-long-random-string
TZ: Europe/London
volumes:
- ./data:/data
restart: unless-stopped
Generate the admin token with openssl rand -base64 48. SIGNUPS_ALLOWED is on for now so you can create your account.
docker compose up -d
2. Nginx in front
sudo nano /etc/nginx/sites-available/vault.example.com
server {
listen 80;
server_name vault.example.com;
client_max_body_size 128M;
location / {
proxy_pass http://127.0.0.1:8222;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
sudo ln -s /etc/nginx/sites-available/vault.example.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d vault.example.com
3. Create your account, then close the door
Open https://vault.example.com, Create account, choose a long master password you can remember — it is the one password you must never lose, and there is no reset. Then:
SIGNUPS_ALLOWED: "false"
in the compose file and docker compose up -d. Nobody else can register. Invite family from the admin page instead.
4. Connect the apps
Install Bitwarden on each device and in each browser. On the login screen, before entering anything, choose Self-hosted (the region/server selector) and enter https://vault.example.com. Log in. Everything syncs.
5. Back it up
The whole vault is in ./data. Add it to your nightly backup (tutorial 23). For SQLite, copy it safely:
sqlite3 ~/docker/vaultwarden/data/db.sqlite3 ".backup '/mnt/backup/vaultwarden.sqlite3'"
Also export from the app occasionally (Settings → Vault → Export, encrypted JSON) and keep the export somewhere safe. Losing this data means losing every password.
Two-factor
Turn on 2FA for your Bitwarden account (Settings → Security → Two-step login, authenticator app) — the vault is the keys to everything. Keep the recovery code offline.
Troubleshooting
App says "cannot connect" or the URL is invalid. Not HTTPS, or the certificate isn't trusted by the device. Test https://vault.example.com in the device's browser first.
Icons for sites don't load. Vaultwarden fetches them from the internet; fine if the server has no outbound access, just cosmetic.
"Invalid admin token". The token in the compose file has changed or has special characters that need quoting. Wrap it in double quotes.
Forgot the master password. It can't be recovered — that's the design. Restore from an export, or start again.
Wrapping up
One container, Nginx with a certificate, create your account, turn sign-ups off, point the real Bitwarden apps at it. You now own your password manager, and the backup of ./data is the most important file on the server.
