Self-host Vaultwarden on a VPS

Run Vaultwarden, the Bitwarden-compatible password server, on your own VPS, claim it over SSH, then put it on your domain with HTTPS and sign-ups closed.

To self-host Vaultwarden, run its official vaultwarden/server Docker image on your server, create your account over a secure connection, and put it behind a reverse proxy with an HTTPS certificate on your own domain. On VPSNine the one-click app does the install, you make your account through an SSH tunnel, and one command, vps9-https vault.example.com, does the HTTPS and closes sign-ups.

Vaultwarden is an independent, community-written server that speaks Bitwarden's API, so the official Bitwarden apps and browser extensions work with it. It isn't made or supported by Bitwarden, Inc.

What you need

  • A server. The Budget plan (2 GB of memory) is plenty: Vaultwarden is one small process with an SQLite database, and the project publishes no minimum. Attachments and Sends are the part that grows, and they live on the disk rather than in memory.
  • A domain or subdomain you can point at the server, such as vault.example.com.
  • An SSH client on your computer. Connect with SSH covers it.

Install it with the one-click app

Order a server with the Vaultwarden one-click app. On the first boot it installs Docker and runs Vaultwarden with its data in /opt/vaultwarden/data, listening on 127.0.0.1:8080 only. Nothing outside the server can reach it yet. It also generates a token for the admin page and keeps it in /root/vaultwarden-admin.txt; Vaultwarden itself only sees an Argon2 hash of it.

When the setup has finished, open a tunnel from your computer, using your server's IPv4 address:

bash
ssh -L 8080:127.0.0.1:8080 root@203.0.113.10

Leave that window open, browse to http://localhost:8080 and create your account. Your browser treats localhost as a secure page, which the web vault needs. Choose a master password you won't forget: nobody, including us, can recover it.

Sign-ups are open only at this stage, and only to someone who can log in to the server over SSH.

Put it on your domain with HTTPS

  1. At your DNS provider, add an A record for vault.example.com with the server's IPv4 address.
  2. Allow ports 80 and 443 in the panel firewall.
  3. On the server, run:
bash
vps9-https vault.example.com

vps9-https installs Caddy from Caddy's own packages, sets Vaultwarden's DOMAIN to https://vault.example.com, turns new sign-ups off (SIGNUPS_ALLOWED=false), recreates the container with those settings, and points Caddy at it. Caddy gets and renews the Let's Encrypt certificate itself, usually within a minute. If the domain doesn't point at the server yet, the command says so; Caddy gets the certificate once it does.

Then, in each Bitwarden app or browser extension, choose a self-hosted server and enter https://vault.example.com.

For the admin page at https://vault.example.com/admin, print its token on the server:

bash
cat /root/vaultwarden-admin.txt

Never serve Vaultwarden over plain HTTP.

Doing it by hand on another server

The project's wiki shows the basic container in Starting a Container. In outline, with Docker installed (Install Docker):

bash
mkdir -p /opt/vaultwarden/data
docker run -d --name vaultwarden --restart unless-stopped \
  -e DOMAIN=https://vault.example.com \
  -v /opt/vaultwarden/data:/data \
  -p 127.0.0.1:8080:80 \
  vaultwarden/server:latest

Binding the port to 127.0.0.1 keeps Vaultwarden off the internet until a reverse proxy with HTTPS sits in front. A two-line Caddyfile does it:

text
vault.example.com {
    reverse_proxy 127.0.0.1:8080
}

The wiki's Enabling HTTPS and Proxy examples pages cover other proxies. Once your own account exists, add -e SIGNUPS_ALLOWED=false and recreate the container so strangers can't register.

Updates and backups

We turn on the operating system's automatic security updates (security fixes only, never an automatic reboot). Vaultwarden itself is yours to update. Read the release notes, then:

bash
docker pull vaultwarden/server:latest
/usr/local/lib/vps9/vaultwarden-run

The second command recreates the container with your settings from /opt/vaultwarden/vaultwarden.env.

Back up /opt/vaultwarden/data off the server: db.sqlite3, the attachments and sends folders, config.json and the rsa_key files. Copy the database with SQLite's .backup command rather than copying the file while it's in use:

bash
apt install -y sqlite3
sqlite3 /opt/vaultwarden/data/db.sqlite3 ".backup '/root/vaultwarden-db-$(date +%F).sqlite3'"

The wiki's Backing up your vault page has the details, and Backups you should run shows how to copy files off the server every night. A snapshot is a useful extra, not a replacement for an off-server copy.

When it goes wrong

  • The web vault won't let you create an account or log in over http://203.0.113.10: the web vault uses the browser's Web Crypto API, which browsers only allow on HTTPS pages and on localhost. Use the SSH tunnel to http://localhost:8080, or run vps9-https and use your domain.
  • A family member can't sign up: sign-ups are closed after vps9-https. Invite them from the admin page; invitations go out by email, so set up SMTP in the admin page first. Without email, set SIGNUPS_ALLOWED=true in /opt/vaultwarden/vaultwarden.env, run /usr/local/lib/vps9/vaultwarden-run, let them register, then set it back to false and run it again.
  • The browser shows a certificate warning: the domain doesn't point at the server yet, or port 80 or 443 is closed in the panel firewall. Check with getent hosts vault.example.com on the server.

Be first when orders open

Join the waitlist and we'll send you one email when VPSNine launches. Pick a plan if you already know which one you want, and we'll size the first servers around it.

  • One email, on launch day
  • Monthly or yearly, no lock-in
  • 14-day money-back guarantee