Deployment guide

Deploy Vaultwarden on a VPS: self-hosted password manager

Deploy on a VPS Cloud →

Security & Monitoring9 min read

Deploy Vaultwarden on a VPS: self-hosted password manager

Vaultwarden is an open-source, Rust-written implementation of the Bitwarden server — lightweight enough to run alongside other services on the smallest VPS, while remaining fully compatible with every official Bitwarden client, on every platform.

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 this model: one container on your VPS, one Docker volume to back up, and without limit user accounts for 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 fork, no custom app, nothing to relearn
  • End-to-end AES-256 encryption: your master password never leaves your device
  • Under 50 MB of RAM at rest — runs comfortably on a 512 MB VPS alongside other services
  • All 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 and 512 MB RAM, with Docker installed (Ubuntu 22.04 LTS recommended). You also need a domain name pointing to your VPS — Bitwarden clients refuse non-HTTPS vaults, so HTTPS is mandatory. Open ports 80 and 443 in your firewall: ufw allow 80 && ufw allow 443.

Deploy Vaultwarden in 5 steps

01

Install Docker

If Docker is not already installed: curl -fsSL https://get.docker.com | sh && systemctl enable --now docker. Verify with docker --version.

02

Start Vaultwarden

Launch 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 port 8000 on localhost.

03

Configure HTTPS with Caddy

Install Caddy: apt install -y caddy. Create /etc/caddy/Caddyfile with: passwords.your-domain.com { reverse_proxy localhost:8000 }. Reload Caddy: systemctl reload caddy. A Let's Encrypt TLS certificate is provisioned automatically and renewed indefinitely — zero configuration.

04

Create your account

Open https://passwords.your-domain.com in your browser. Click "Create Account", choose a strong master password (it encrypts everything locally before anything is sent to the server), and your vault is active immediately.

05

Lock down registrations

Once all accounts are created, stop the container and relaunch it adding -e SIGNUPS_ALLOWED=false 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).

06

First login

When you first open the URL, Vaultwarden displays the Bitwarden web vault: click "Create account" and set your own email and master password (it is not recoverable by anyone, not even by us). Do this IMMEDIATELY: registration is open.

Configure SMTP and email-based 2FA

Vaultwarden can send emails for address verification, password reset, organization invitations and email-based two-factor authentication (_ENABLE_EMAIL_2FA=true). That last point deserves attention: if SMTP is not configured or misconfigured, email 2FA is declared active but never sends anything — the code never arrives, the user can no longer log in, and Vaultwarden surfaces no visible error.

The most common confusion involves ports and encryption. Two values coexist and are not interchangeable:

- Port 465 with SMTP_SECURITY=force_tls — TLS connection from the start (formerly "SMTPS"). Compatible with most ISPs and corporate relays.
- Port 587 with SMTP_SECURITY=starttls — plain connection that upgrades to TLS via the STARTTLS command. Expected by most modern SMTP providers (SendGrid, Brevo, Postmark, Gmail SMTP).

Using force_tls on port 587 — or starttls on port 465 — silently fails the SMTP connection: Vaultwarden logs nothing, emails don't go out, and the interface shows "sent" if you test from the admin panel. The only signal is the missing email on the recipient side.

Configure SMTP correctly

01

Choose port and security based on your provider

Check the documentation of your SMTP relay (Gmail, Brevo, Postmark, SendGrid…). Practical rule: if your provider specifies port 465SMTP_SECURITY=force_tls; if it specifies port 587SMTP_SECURITY=starttls. Never mix the two.

02

Pass SMTP variables to the container

Relaunch the container with the required variables:

docker run -d --name vaultwarden --restart=always \
  -v vaultwarden:/data \
  -p 127.0.0.1:8000:80 \
  -e SMTP_HOST=smtp.your-provider.com \
  -e [email protected] \
  -e SMTP_PORT=587 \
  -e SMTP_SECURITY=starttls \
  -e SMTP_USERNAME=your_login \
  -e SMTP_PASSWORD=your_password \
  vaultwarden/server:latest
03

Test sending from the admin panel

Open https://passwords.your-domain.com/admin, scroll to the SMTP Email Settings section and use the Send test email button. If the email doesn't arrive within 60 seconds, check the container logs: docker logs vaultwarden 2>&1 | grep -i smtp. A Connection refused message indicates the wrong port; a TLS handshake error indicates a security mismatch.

04

Enable email 2FA only after validating sending

Only enable _ENABLE_EMAIL_2FA=true once the test send is confirmed. If you enable it first, users whose client requests a code receive nothing and get locked out. To unblock a locked account: open /admin, locate the user and click Deactivate TOTP to temporarily disable 2FA.

Client/server compatibility and silent errors

Recent Bitwarden clients introduced a new initial authentication flow that calls the /identity/accounts/prelogin/password endpoint. Vaultwarden instances pinned to a version earlier than 1.36.0 don't know this endpoint and return a 404 with no explicit message — the client simply displays a generic connection failure. The trap is insidious: devices already connected before the client update continue working normally, because their session is already established and doesn't go through this new authentication path. Only new devices fail. If you run curl https://your-domain.com/identity/accounts/prelogin/password -X POST -d '{"email":"[email protected]"}' -H 'Content-Type: application/json' and get a 404, your server is too old.

Symptoms of a client/server version mismatch

  • Cannot log in on a new device or browser, while existing devices work normally
  • Generic error message with no cause indicated ("An error has occurred" or "Invalid username or password")
  • Freshly installed Chrome or Firefox extension fails, but the same version on another machine works
  • The Bitwarden web vault hosted on your instance returns 404 on /identity/accounts/prelogin/password
  • No errors in server-side Vaultwarden logs — the endpoint doesn't exist, there's nothing to log
  • The problem appeared after an automatic Bitwarden client update on the new device

Diagnose and resolve the mismatch

01

Check your server version

Query the version endpoint: curl https://your-domain.com/api/version. If the response shows a version earlier than 1.36.0, your server doesn't support the new authentication flow used by recent clients.

02

Update to the latest image

The safest approach is to always use vaultwarden/server:latest and keep the image up to date. To update: docker pull vaultwarden/server:latest && docker stop vaultwarden && docker rm vaultwarden, then rerun the same docker run command as at installation. Vaultwarden preserves data in the volume — no manual migration needed.

03

Verify the update took effect

After restarting, query curl https://your-domain.com/api/version again and confirm the version is 1.36.0 or higher. Then test login from a new private browsing tab.

04

Pin a version if stability is the priority

If you prefer to control updates manually, use a versioned tag: vaultwarden/server:1.37.2 for example. In that case, monitor releases on GitHub and update whenever a new Bitwarden client version is deployed — the two are coupled.

Regression in 1.37.1: master password change blocked

Version 1.37.1 contains a known regression (GitHub issue #7659): the master password change request returns HTTP 422 with the message missing field newMasterPasswordHash. The operation fails server-side without the client providing useful information. The fix is in version 1.37.2, released shortly after. If you pinned version 1.37.1, upgrade directly to 1.37.2 — the command is the same as any other update: docker pull vaultwarden/server:1.37.2 && docker stop vaultwarden && docker rm vaultwarden, then relaunch the container with the new tag.

SIGNUPS_ALLOWED=false trap: only set it after creating the admin account

A common installation mistake: setting -e SIGNUPS_ALLOWED=false before creating the administrator account. Result — your own instance refuses account creation and you can no longer log in. The order is mandatory: (1) start without this parameter, (2) immediately create your admin account via the web interface, (3) only then relaunch the container with SIGNUPS_ALLOWED=false. If you've already locked yourself out, the escape hatch is to enable the admin panel via -e ADMIN_TOKEN=$(openssl rand -base64 48) and invite the admin user from /admin.

Daily backups in one cron line

Add this to the root 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 every night at 3 AM — the entire vault (SQLite file + attachments) lands in /backup as a timestamped archive. Send this directory to S3 or Backblaze B2 with rclone for off-site protection.

Official documentation

For advanced configuration and tool-specific options, refer to the official Vaultwarden documentation. This guide covers getting online on a VPS; the vendor docs remain the reference for fine-tuning, major updates and specific use cases.

Deploy Vaultwarden on your VPS

Order a ServOrbit VPS, deploy Vaultwarden in minutes, and own your password vault forever.

Need help?

Browse our help center and FAQ, or reach our team — callback, WhatsApp or email. Support in French, English and Arabic.

Message us on WhatsAppopens in a new tab