Self-host Vaultwarden on a managed VPS: your passwords on your own server

When you self-host Vaultwarden on a managed VPS, your passwords and your team’s stay on a machine of your own, which our teams keep up to date and monitor day and night. Vaultwarden is free software under the AGPL-3.0 license. This guide follows its official documentation: installing with Docker Compose, HTTPS, closing signups, the admin token, what protects the vault, the database, email, backups and updates.

Simon Vasconcelos Lee By Published on 8 November 202614 minute read

All guides

In short

  1. The AGPL-3.0 license lets you run Vaultwarden freely, at work or anywhere else; if you modify it, you offer the source code of your version to the people who use it.
  2. Install it with Docker Compose: one image, a port published locally and a data folder, behind a reverse proxy.
  3. HTTPS is essential to the web vault: serve Vaultwarden under its own domain name and set that name in DOMAIN.
  4. Create your account, then close signups with SIGNUPS_ALLOWED: by default, anyone who reaches the instance can register. A strong master password and two-factor authentication then protect the vault.
  5. Back up the database and attachments every day, test the restore, and update with docker compose pull.

What Vaultwarden does

Vaultwarden is a password management server written in Rust, designed for self-hosting. Its wiki aims it at individuals, families and organizations on a human scale. The web vault ships inside its Docker images.

It implements an API compatible with official Bitwarden clients, in the browser, on the desktop and on mobile. The README states that the project is not associated with Bitwarden or Bitwarden, Inc., and it asks you to report any problem directly to the project, whichever client you use, rather than to the official support channels.

The wiki also lists what is missing compared with the official server, such as login with passkeys, custom roles and certain enterprise policies. It adds that features mainly useful to larger organizations are not a project priority: read that list if you need them.

What the AGPL-3.0 license allows

Vaultwarden is published under the GNU Affero General Public License, version 3. The text affirms an unlimited permission to run the unmodified program. You can therefore use the image published by the project for your company and your team, with no license to buy.

Section 13 adds a condition specific to the AGPL: if you modify the program, your version must offer everyone who uses it remotely over a network a way to get its source code at no charge.

Installing with Docker Compose

The README recommends the container images. On a server with Docker installed, create a folder and put this compose.yaml in it, drawn from the README and the wiki:

compose.yaml
services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    environment:
      DOMAIN: "https://vault.example.com"
      SIGNUPS_ALLOWED: "true"
    volumes:
      - ./vw-data/:/data/
    ports:
      - 127.0.0.1:8000:80
Terminal
docker compose up -d

Your domain name points to the server with A and AAAA records, and visitors arrive on ports 80 and 443. Until the reverse proxy is in place, the web vault stays unusable: move straight on to the next section.

The project gives no memory or CPU figures; it only presents itself as a solution for cases where the resource-heavy official service is not a good fit. The size depends on the number of accounts and the volume of attachments. On a managed VPS, describe your use to us and we will recommend the right size.

HTTPS and WebSocket: the reverse proxy

The web vault relies on the Web Crypto API, which browsers reserve for secure contexts: the README says it only works once HTTPS is enabled, and the wiki calls HTTPS “pretty much required.” The project recommends a reverse proxy in front of Vaultwarden and advises against the TLS built into its Rocket framework.

Use a widely trusted certificate, such as the Let’s Encrypt certificates the wiki recommends: some platforms refuse the connection with a self-signed certificate. The certificate must include its full chain, or Android devices will fail to connect.

WebSocket notifications, on by default, tell the browser, the desktop app and the extension that an entry has changed. They use the main HTTP port, and the proxy must pass along the Upgrade and Connection headers. Mobile apps use their system’s native push notifications, which are configured separately.

With Caddy

The wiki suggests looking at Caddy first if you have no preference: it enables HTTPS on its own, gets the Let’s Encrypt certificate and supports WebSocket. The wiki’s setting also passes the visitor’s real address to Vaultwarden, for its logs:

Caddyfile
vault.example.com {
  reverse_proxy 127.0.0.1:8000 {
    header_up X-Real-IP {remote_host}
  }
}

With Nginx and Certbot

This block follows the wiki’s Nginx example, reduced to port 80 so that Certbot can set up HTTPS:

Nginx block
upstream vaultwarden-default {
  zone vaultwarden-default 64k;
  server 127.0.0.1:8000;
  keepalive 2;
}

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      "";
}

server {
    listen 80;
    listen [::]:80;
    server_name vault.example.com;

    client_max_body_size 525M;

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;

    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;

    location / {
      proxy_pass http://vaultwarden-default;
    }
}

Certbot then installs the certificate and takes care of renewing it:

Terminal
sudo certbot --nginx

Checking WebSocket

Open the browser’s developer tools, network tab, WS filter, then log back in to the vault: a 101 response on /notifications/hub confirms the connection. Another test from the wiki: open the vault in two browsers, rename an entry in one, and the change appears right away in the other.

Closing signups

By default, anyone who reaches your instance can create an account on it. That is useful for your first account, and the wiki recommends closing signups afterward, to keep an attacker from creating one.

  1. Open your HTTPS address and create your account, then connect your apps to that address.
  2. Set SIGNUPS_ALLOWED to "false" in compose.yaml.
  3. Restart with docker compose up -d: an environment variable is bound to the container, which has to be recreated to pick it up.
compose.yaml, under environment
SIGNUPS_ALLOWED: "false"

As soon as you save the configuration from the admin page, a config.json file appears in the data folder and takes precedence over environment variables. The settings concerned are then changed from that page: editing compose.yaml is no longer enough.

The admin page and its token

The /admin page lets you configure Vaultwarden, view and delete accounts and organizations, remove a user’s two-factor authentication, send invitations and read the diagnostics. Without ADMIN_TOKEN, it stays disabled: if you have no use for it, leave it that way.

The wiki strongly recommends enabling HTTPS before this page. The token acts as a password, and it can be kept in hashed form, with argon2id, rather than in plain text in the configuration. Vaultwarden provides the command: it asks for the password twice, then returns a PHC string.

Terminal
docker run --rm -it vaultwarden/server /vaultwarden hash

Put this string in a .env file, next to compose.yaml, in single quotes, then call it from the service:

.env
VAULTWARDEN_ADMIN_TOKEN='$argon2id$...'
compose.yaml, under environment
ADMIN_TOKEN: ${VAULTWARDEN_ADMIN_TOKEN}

Check the result, restart, then log in at /admin with your password, not with the PHC string:

Terminal
docker compose config
docker compose up -d

What protects the vault

The first protection is the master password. Vault data is encrypted with personal or organization keys: anyone who gets a copy of the database or forges a session still has to crack this password to read it. Its strength therefore comes first. Even an admin session can delete an account or remove two-factor authentication without giving access to vault data.

ProtectionWhat it bringsWhere it is set
Master passwordKeeps data encrypted, even if a copy of the database gets outEach user chooses it, long and used only for this vault
Two-factor authenticationWithout it, the wiki points out that brute-forcing a password remains possible in theoryIn each account; an organization policy can require it
HTTPSEncrypts the path between client and serverThe reverse proxy
Closed signupsKeeps strangers from creating an accountSIGNUPS_ALLOWED
Password hintsShown on the page, they would help guess a password; version 1.37.5 keeps them hidden by defaultLeave SHOW_PASSWORD_HINT at false; PASSWORD_HINTS_ALLOWED removes them altogether
Attempt limitsSlows down tries from a single address, for login and /adminLOGIN_RATELIMIT_SECONDS and ADMIN_RATELIMIT_SECONDS
Fail2banBlocks addresses after too many failures, which the wiki considers especially important for a public instanceOn the server, from a LOG_FILE log

Plan for a forgotten master password before it happens: turn on emergency access for your account and, in an organization, account recovery, which requires email to be configured.

Three more settings from the hardening guide

SQLite, MariaDB or PostgreSQL

The same image supports all three databases. The wiki describes SQLite as the most widely used and tested, and recommends it for most uses, unless you have a specific need for another.

DatabaseSetupBackup
SQLiteNone: one file, vw-data/db.sqlite3The /vaultwarden backup command, or a copy of the folder with the service stopped
MariaDB or MySQLYour database server, and DATABASE_URL as mysql://A database dump, on top of the vw-data folder
PostgreSQLYour database server, and DATABASE_URL as postgresql://A database dump, on top of the vw-data folder
compose.yaml, under environment (PostgreSQL)
DATABASE_URL: "postgresql://user_name:user_password@db_host:5432/vaultwarden"

Create an empty database and its user: on startup, Vaultwarden sets up its own schema there. A password with special characters is written with percent-encoding in this address.

Make this choice before filling the vault. The wiki describes a move from SQLite to PostgreSQL with pgloader, noting that this route is not supported by the project, that it is at your own risk and that it starts with a backup.

Email: the SMTP configuration

Vaultwarden starts without email, but several features depend on it: invitations, address verification, sending password hints, two-factor authentication by email and account recovery.

On a Simafri VPS, sending goes through an authenticated SMTP relay, on port 587: the address of an email account you already have, or Simafri Suite. The password goes in the .env file, like the admin token:

compose.yaml, under environment
SMTP_HOST: "smtp.example.com"
SMTP_FROM: "vault@example.com"
SMTP_PORT: "587"
SMTP_SECURITY: "starttls"
SMTP_USERNAME: "vault@example.com"
SMTP_PASSWORD: ${VAULTWARDEN_SMTP_PASSWORD}

If nothing goes out, the wiki suggests testing the connection to the relay from the server. The command returns 0 when the relay answers:

Terminal
timeout 5 bash -c 'cat < /dev/null > /dev/tcp/smtp.example.com/587'; echo $?

Backups

The README notes that the project cannot be held liable for data loss and highly recommends regular backups. The wiki advises automating them, with at least one copy elsewhere. Here is what the data folder holds with SQLite:

ItemWhat it holdsBackup
db.sqlite3Almost all data: accounts, organizations, vaultsRequired
attachments/Attachments, stored outside the databaseRequired
config.jsonThe admin page configuration, including sensitive data in plain textRecommended, encrypted
rsa_key*The keys that sign sessions; losing them logs users outRecommended, encrypted
sends/Files sent with Send, short-lived by natureOptional
icon_cache/Website icons, downloaded again as neededOptional

The database, with the service running

Since version 1.32.1, Vaultwarden can back up its SQLite database by itself, without stopping the service:

Terminal
docker exec -it vaultwarden /vaultwarden backup

The command writes a db_YYYYMMDD_HHMMSS.sqlite3 file next to the database, in vw-data. The image includes neither sqlite3 nor cron: the wiki advises scheduling the job on the server, at least once a day. Remove -it in that case, since a scheduled job has no terminal, and sort through these files, which pile up.

The whole folder, with the service stopped

When the database is not in use, a plain copy of all its files is enough. This is the stopped-service method the wiki gives as an example for Docker, and it takes the attachments along too:

Terminal, in the compose.yaml folder
docker compose down
tar -czf vaultwarden-$(date +%F).tar.gz vw-data
docker compose up -d

The wiki considers a layer of encryption useful, especially when the backup includes the admin token and SMTP credentials, and it mentions rclone, restic and rustic for sending copies elsewhere. With MariaDB or PostgreSQL, add a database dump to the vw-data folder.

The wiki asks you not to rely on disk snapshots alone, as they are harder to restore. So keep these application-level copies: stored on the server’s disk, they are also part of its nightly backups.

Restoring

  1. Stop Vaultwarden.
  2. Replace each file or folder in vw-data with its backed-up version.
  3. If the database comes from /vaultwarden backup, name it db.sqlite3 and first delete any existing db.sqlite3-wal file: a mismatched log can corrupt the database. If it comes from a direct copy, restore db.sqlite3 and its db.sqlite3-wal together.
  4. Start it again, then check that you can open the vault.

The wiki advises repeating this exercise from time to time, keeping a copy of the live data: that is how you check that a backup works.

Updates

The wiki gives two commands, from the compose.yaml folder. The data folder stays in place:

Terminal
docker compose pull
docker compose up -d

These updates matter more than most. Mobile apps and browser extensions update themselves, and the wiki warns that a version gap with the server can cause sudden breakage. The web vault, shipped in the image, always stays matched to its server.

The project has no release schedule: follow its release notes, and run a backup right before each update. Some carry security fixes, like 1.37.5 of November 1, 2026, whose notes advise updating as soon as possible. These notes also warn that, since 1.37.5, an invalid configuration value stops Vaultwarden from starting: read over your environment file before updating. The diagnostics page at /admin shows whether a newer version exists.

Who does what on a managed VPS

Self-hosting means running the server on top of the application. On a managed VPS, our teams take charge of the server and proactively monitor your instance; Vaultwarden remains your software, with its settings and its data.

TopicOur teamsYou
The serverSystem and security updates, server interventions includedThe timing that suits your business
MonitoringServer monitored 24/7, with intervention without waiting for your callReading your instance’s logs
VaultwardenProactive monitoring: errors, slowdowns and disk space spotted, fix recommendedIts installation, updates and settings, which you apply, yourself or through your AI assistant
Accounts and the vaultThe server that carries them, monitored and backed upUsers, invitations, master passwords and two-factor authentication
BackupsEvery night, encrypted and kept off the machine; restores includedVaultwarden’s own copies, and the restore request, when you need one
MigrationYour current server migrated, free of chargeThe timing of the switch

If you would rather have our teams work inside the application itself, that service is billed by the hour or at a fixed rate, with an estimate shared before the work starts.

Vaultwarden, on a server run for you

With a Simafri Managed VPS, our teams keep your Vaultwarden instance’s server up to date, monitor it day and night and step in without waiting for your call; they also proactively monitor your instance and recommend useful fixes, which you apply, yourself or through your AI assistant. Backups are encrypted every night and kept off the machine, restores are included, and migrating your current server is free.

Explore Managed VPS

Frequently asked questions

Is Vaultwarden free for a business?

Yes. Vaultwarden is under the AGPL-3.0 license: you can run it at work with no license to buy. If you modify it, your version must offer its source code to the people who use it over the network. What remains is the cost of the server that runs it.

Does Vaultwarden work with Bitwarden apps?

Yes. The README presents Vaultwarden as compatible with official Bitwarden clients, while stating that the project is not associated with Bitwarden or Bitwarden, Inc. Problems are therefore reported to the Vaultwarden project, whichever client you use.

How do I install Vaultwarden with Docker Compose?

Create a compose.yaml with the vaultwarden/server image, a data folder and the port published on 127.0.0.1, then run docker compose up -d. Next, put an HTTPS reverse proxy in front: without HTTPS, the web vault does not work. Also set your address in DOMAIN.

How do I disable signups on Vaultwarden?

Once your account exists, set SIGNUPS_ALLOWED to false in compose.yaml, then run docker compose up -d again. Organizations can still send invitations: INVITATIONS_ALLOWED set to false removes that option. If the admin page has already saved its configuration, make this change from there.

How do I set the Vaultwarden admin token?

Run the vaultwarden hash command, which returns an argon2id string, then put it in ADMIN_TOKEN, from a .env file with Docker Compose. You then log in at /admin with your password. Without ADMIN_TOKEN, the page stays disabled.

What protects a Vaultwarden vault?

First, the master password: data is encrypted, and a copy of the database can only be read by cracking it. On top of that come two-factor authentication, HTTPS, closed signups, a hashed admin token and encrypted backups.

How do I back up Vaultwarden?

With SQLite, run the /vaultwarden backup command in the container every day, and also copy the attachments folder, config.json and the rsa_key files. With MariaDB or PostgreSQL, add a database dump. Test the restore regularly.

Does a managed VPS cover Vaultwarden?

A managed VPS covers the server: system, security, monitoring and backups. Our teams also proactively monitor your instance and recommend useful fixes, which you apply. Work inside the application is billed by the hour or at a fixed rate.

Contact us