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.
By Simon Vasconcelos Lee
Published on 8 November 202614 minute read
DOMAIN.SIGNUPS_ALLOWED: by default, anyone who reaches the instance can register. A strong master password and two-factor authentication then protect the vault.docker compose pull.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.
/admin page for settings, accounts and diagnostics.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.
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.
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:
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
docker compose up -d
127.0.0.1: as in the README, Vaultwarden is reached only through the reverse proxy, set up on the same server.DOMAIN: the base address of your instance, in https. The wiki warns that features break without it, including attachments and invitation links.vw-data folder on a local disk: it holds all the data. The wiki points out SQLite’s trouble on a CIFS or Samba volume, which does not support locking.latest tag tracks the latest released version, and the wiki recommends it for most uses. A tag like 1.37.5 pins a version, and latest-alpine gives the same thing on an Alpine base.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.
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.
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:
vault.example.com {
reverse_proxy 127.0.0.1:8000 {
header_up X-Real-IP {remote_host}
}
}
This block follows the wiki’s Nginx example, reduced to port 80 so that Certbot can set up HTTPS:
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:
sudo certbot --nginx
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.
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.
SIGNUPS_ALLOWED to "false" in compose.yaml.docker compose up -d: an environment variable is bound to the container, which has to be recreated to pick it up.SIGNUPS_ALLOWED: "false"
INVITATIONS_ALLOWED set to "false" removes that option, and the wiki leaves the choice to how much you trust your users.SIGNUPS_DOMAINS_WHITELIST limits signups to certain email domains, and SIGNUPS_VERIFY set to true then requires verifying the address. When this list is set, SIGNUPS_ALLOWED is ignored.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 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.
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:
VAULTWARDEN_ADMIN_TOKEN='$argon2id$...'
ADMIN_TOKEN: ${VAULTWARDEN_ADMIN_TOKEN}
Check the result, restart, then log in at /admin with your password, not with the PHC string:
docker compose config
docker compose up -d
ADMIN_SESSION_LIFETIME. An open session stays valid after a token change. To end them all, delete rsa_key.pem from the data folder and restart, which also logs users out and cancels pending invitations./admin only to certain addresses, or to add HTTP authentication.DISABLE_ADMIN_TOKEN removes all control: it is meant for a separate authentication layer placed in front, and the wiki reserves it for those who know what they are doing.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.
| Protection | What it brings | Where it is set |
|---|---|---|
| Master password | Keeps data encrypted, even if a copy of the database gets out | Each user chooses it, long and used only for this vault |
| Two-factor authentication | Without it, the wiki points out that brute-forcing a password remains possible in theory | In each account; an organization policy can require it |
| HTTPS | Encrypts the path between client and server | The reverse proxy |
| Closed signups | Keeps strangers from creating an account | SIGNUPS_ALLOWED |
| Password hints | Shown on the page, they would help guess a password; version 1.37.5 keeps them hidden by default | Leave SHOW_PASSWORD_HINT at false; PASSWORD_HINTS_ALLOWED removes them altogether |
| Attempt limits | Slows down tries from a single address, for login and /admin | LOGIN_RATELIMIT_SECONDS and ADMIN_RATELIMIT_SECONDS |
| Fail2ban | Blocks addresses after too many failures, which the wiki considers especially important for a public instance | On 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.
root by default, and the wiki considers it better to give it the fewest privileges. Add user: 1000:1000 to the service, with a vw-data folder owned by that user.access_token. If your proxy keeps logs or ships them to an outside service, the wiki recommends redacting this value there./var/run/docker.sock.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.
| Database | Setup | Backup |
|---|---|---|
| SQLite | None: one file, vw-data/db.sqlite3 | The /vaultwarden backup command, or a copy of the folder with the service stopped |
| MariaDB or MySQL | Your database server, and DATABASE_URL as mysql:// | A database dump, on top of the vw-data folder |
| PostgreSQL | Your database server, and DATABASE_URL as postgresql:// | A database dump, on top of the vw-data folder |
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.
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:
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}
DOMAIN, and stay valid for 5 days.No compatible authentication mechanism was found.config.json.If nothing goes out, the wiki suggests testing the connection to the relay from the server. The command returns 0 when the relay answers:
timeout 5 bash -c 'cat < /dev/null > /dev/tcp/smtp.example.com/587'; echo $?
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:
| Item | What it holds | Backup |
|---|---|---|
db.sqlite3 | Almost all data: accounts, organizations, vaults | Required |
attachments/ | Attachments, stored outside the database | Required |
config.json | The admin page configuration, including sensitive data in plain text | Recommended, encrypted |
rsa_key* | The keys that sign sessions; losing them logs users out | Recommended, encrypted |
sends/ | Files sent with Send, short-lived by nature | Optional |
icon_cache/ | Website icons, downloaded again as needed | Optional |
Since version 1.32.1, Vaultwarden can back up its SQLite database by itself, without stopping the service:
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.
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:
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.
vw-data with its backed-up version./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.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.
The wiki gives two commands, from the compose.yaml folder. The data folder stays in place:
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.
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.
| Topic | Our teams | You |
|---|---|---|
| The server | System and security updates, server interventions included | The timing that suits your business |
| Monitoring | Server monitored 24/7, with intervention without waiting for your call | Reading your instance’s logs |
| Vaultwarden | Proactive monitoring: errors, slowdowns and disk space spotted, fix recommended | Its installation, updates and settings, which you apply, yourself or through your AI assistant |
| Accounts and the vault | The server that carries them, monitored and backed up | Users, invitations, master passwords and two-factor authentication |
| Backups | Every night, encrypted and kept off the machine; restores included | Vaultwarden’s own copies, and the restore request, when you need one |
| Migration | Your current server migrated, free of charge | The 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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
Simafri
Let's talk about your project
Tell us what you need in a few words: we will get back to you quickly.
Thank you! Your request has been sent. We'll get back to you shortly.
Prefer email? Write to us at support@simafri.com.