Why Self-Host Your Password Manager?
Cloud password managers charge per user per month, store your encrypted vault on servers you don't control, and can disappear or raise prices overnight. Vaultwarden flips that model: one container on your VPS, one Docker volume to back up, and without user limits users at a fixed infrastructure cost. Because Vaultwarden speaks the Bitwarden protocol, every Bitwarden client — Chrome extension, Firefox add-on, iOS, Android, Windows, Linux, CLI — connects to your self-hosted instance without any modification.
Key benefits
- 100% compatible with all official Bitwarden clients — no forks, no custom apps, no relearning
- End-to-end AES-256 encryption: your master password never leaves your device
- Under 50 MB RAM at idle — runs comfortably on a 512 MB VPS alongside other services
- Without user limits users and organization vaults with encrypted sharing and role-based access
- Built-in TOTP authenticator: replace Google Authenticator with a self-hosted alternative
- Emergency access — grant a trusted contact read access after a configurable waiting period
Prerequisites
You need a VPS with at least 1 vCPU, 512 MB RAM, and Docker installed (Ubuntu 22.04 LTS recommended). You also need a domain name pointing to the VPS — Bitwarden clients refuse non-HTTPS vaults, so HTTPS is mandatory. Allow ports 80 and 443 through your firewall: ufw allow 80 && ufw allow 443.
Deploy Vaultwarden in 5 steps
Install Docker
If Docker is not already installed: curl -fsSL https://get.docker.com | sh && systemctl enable --now docker. Verify with docker --version.
Start Vaultwarden
Run the container: docker run -d --name vaultwarden --restart=always -v vaultwarden:/data -p 127.0.0.1:8000:80 -e WEBSOCKET_ENABLED=true vaultwarden/server:latest. The server starts in under a second and listens on localhost port 8000.
Set up HTTPS with Caddy
Install Caddy: apt install -y caddy. Create /etc/caddy/Caddyfile with: passwords.yourdomain.com { reverse_proxy localhost:8000 }. Reload Caddy: systemctl reload caddy. A Let's Encrypt TLS certificate is provisioned automatically and renewed forever — zero configuration.
Create your account
Open https://passwords.yourdomain.com in your browser. Click 'Create Account', pick a strong master password (it encrypts everything locally before anything is sent to the server), and your vault is live immediately.
Lock down registrations
Once all accounts are created, stop the container and restart it with -e SIGNUPS_ALLOWED=false added to the docker run command. Your instance is now invite-only. For ongoing user management, enable the admin panel by adding -e ADMIN_TOKEN=$(openssl rand -base64 48).
Logging in for the first time
When you first open the URL, Vaultwarden shows the Bitwarden web vault: click "Create account" and set your own e-mail address and master password (nobody can recover it, not even us). Do this IMMEDIATELY: registration is open.
Client/Server Compatibility and Silent Failures
Recent Bitwarden clients introduced a new initial authentication flow that calls the /identity/accounts/prelogin/password endpoint. Vaultwarden instances running versions older than 1.36.0 do not know this endpoint and return a 404 error with no explicit message — the client simply shows a generic login failure. The trap is subtle: devices already logged in before the client update continue working normally, because their session is already established and bypasses this new authentication path. Only new devices fail. Run curl https://yourdomain.com/identity/accounts/prelogin/password -X POST -d '{"email":"[email protected]"}' -H 'Content-Type: application/json' — a 404 response means your server is too old.
Symptoms of a client/server version mismatch
- Login fails on a new device or browser, while existing devices work normally with the same account
- Generic error message with no indication of the root cause ("An error has occurred" or "Invalid username or password")
- A freshly installed Chrome or Firefox extension fails, but the identical version on another machine works
- The Bitwarden web vault hosted on your instance returns 404 on
/identity/accounts/prelogin/password - No error in Vaultwarden server logs — the endpoint does not exist, so there is nothing to log
- The problem appeared after an automatic Bitwarden client update on the new device
Diagnose and fix the mismatch
Check your server version
Query the version endpoint: curl https://yourdomain.com/api/version. If the response shows a version older than 1.36.0, your server does not support the new authentication flow required by recent clients.
Update to the latest image
The safest approach is to always use vaultwarden/server:latest and keep the image current. To update: docker pull vaultwarden/server:latest && docker stop vaultwarden && docker rm vaultwarden, then re-run the same docker run command used at installation. Vaultwarden preserves all data in the named volume — no manual migration required.
Verify the update took effect
After restarting, query curl https://yourdomain.com/api/version again and confirm the version is 1.36.0 or later. Then test login from a fresh private browsing tab.
Pin a version if stability is a priority
If you prefer to control updates manually, use a versioned tag: vaultwarden/server:1.37.0 for example. In that case, monitor GitHub releases and update whenever a new Bitwarden client version ships — the two are tightly coupled.
SIGNUPS_ALLOWED=false trap: only set it after creating your admin account
A common installation mistake: setting -e SIGNUPS_ALLOWED=false before creating the administrator account. The result — your own instance refuses to let you register and you cannot log in at all. The order is mandatory: (1) start without this parameter, (2) immediately create your admin account through the web interface, (3) then restart the container with SIGNUPS_ALLOWED=false. If you have already locked yourself out, the emergency exit is to enable the admin panel with -e ADMIN_TOKEN=$(openssl rand -base64 48) and invite the admin user from /admin.
Daily backups in one cron line
Add this to root's crontab (crontab -e): 0 3 * * * docker run --rm -v vaultwarden:/data -v /backup:/out busybox tar czf /out/vaultwarden-$(date +%F).tar.gz /data. Run it daily at 3 AM — the entire vault (SQLite file + attachments) lands in /backup as a timestamped archive. Send that directory to S3 or Backblaze B2 with rclone for off-site protection.
The Official Documentation
For advanced configuration and tool-specific options, refer to the official Vaultwarden documentation. This guide covers going live on a VPS; the vendor's documentation remains the reference for fine-tuning, major upgrades and specific use cases.