Self-Hosting Vaultwarden: Your Own Password Manager
Set up Vaultwarden on Docker to self-host your Bitwarden-compatible password vault. Full walkthrough including HTTPS setup and mobile app configuration.
Vaultwarden is a self-hosted implementation of the Bitwarden server API, written in Rust. It’s lightweight, fully compatible with the Bitwarden browser extensions and mobile apps, and runs in a single Docker container without any external database.
The pitch is simple: your passwords are your most sensitive data. Why store them on a server owned by a company that could be breached, sold, or go out of business? Vaultwarden puts that data on hardware you control.
I’ve been running it for two years. My wife uses it. We have browser extensions on every device. It works exactly like Bitwarden cloud — because it is Bitwarden, just self-hosted.
For Docker setup basics, see Docker Compose for Beginners. This guide assumes Docker and Docker Compose are installed on your server.
What you get
- Full Bitwarden password vault (passwords, notes, cards, identities)
- Browser extensions for Chrome, Firefox, Safari, Edge (use official Bitwarden extensions)
- iOS and Android apps (official Bitwarden apps, pointed at your server)
- Bitwarden Send (encrypted file/text sharing)
- TOTP 2FA generation (replaces Authy/Google Authenticator)
- Organizations and collections (free — requires paid in Bitwarden cloud)
- Passkey support (Bitwarden recent versions)
Prerequisites
- Docker and Docker Compose installed
- A domain name pointing to your server, OR willingness to use Tailscale for access
- SSL certificate (required for Bitwarden clients to connect)
On the SSL requirement: Bitwarden clients require HTTPS to connect. You can’t use Vaultwarden over plain HTTP in production. The two practical options are:
- Nginx Proxy Manager with Let’s Encrypt — for access via a domain name (see the NPM setup guide)
- Tailscale + a self-signed cert — for access only within your tailnet
This guide assumes you’ll use NPM with a domain. If you’re Tailscale-only, adapt accordingly.
Step 1: Create the directory
mkdir -p ~/docker/vaultwarden/data
Vaultwarden uses SQLite by default — the entire database lives in data/db.sqlite3. No separate database container required.
Step 2: Write the Docker Compose file
Create ~/docker/vaultwarden/docker-compose.yml:
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: unless-stopped
ports:
- "8543:80"
volumes:
- ./data:/data
environment:
TZ: America/New_York
DOMAIN: https://vault.yourdomain.com
SIGNUPS_ALLOWED: "false"
ADMIN_TOKEN: ""
LOG_LEVEL: warn
EXTENDED_LOGGING: "true"
Important settings to configure:
DOMAIN — Set this to your full domain name including https://. Vaultwarden uses this for HTTPS redirects and WebAuthn/passkey functionality. If it’s wrong, some features won’t work.
SIGNUPS_ALLOWED: "false" — After you create your account, disable signups so random people can’t register on your server. Set this to "true" only during initial setup.
ADMIN_TOKEN — Leave blank initially. After setup, generate a secure token here to access the admin panel at /admin. Generate one with: openssl rand -base64 48
Step 3: Start Vaultwarden
cd ~/docker/vaultwarden
docker compose up -d
Check logs:
docker compose logs -f vaultwarden
You should see Vaultwarden start in a few seconds. It’s a small binary — it starts faster than almost any other Docker container.
Step 4: Set up HTTPS with Nginx Proxy Manager
In NPM, add a new Proxy Host:
- Domain Name:
vault.yourdomain.com - Scheme:
http - Forward Hostname: your server IP or
vaultwarden(if NPM is on the same Docker network) - Forward Port:
8543 - Enable WebSockets: Yes
- SSL: Request a Let’s Encrypt certificate, enable “Force SSL” and “HTTP/2 Support”
Vaultwarden uses WebSockets for real-time sync between devices — the “Enable WebSockets” setting in NPM is not optional.
After NPM applies the certificate, test that https://vault.yourdomain.com loads the Vaultwarden login page. You should see the Bitwarden logo and a login form.
Step 5: Create your account
While SIGNUPS_ALLOWED is still "true", navigate to https://vault.yourdomain.com/#/register and create your admin account.
Use a strong master password. This is the password that encrypts everything in your vault — if you lose it, there is no recovery. Bitwarden’s encryption model means even you can’t recover a forgotten master password.
Write it down. Put it in a physical safe. Store it somewhere it will survive your house burning down. Melodramatic? Maybe. But this is the one password where losing it is genuinely catastrophic.
After creating your account, log in and verify everything works.
Step 6: Disable signups
After your account is created, set SIGNUPS_ALLOWED: "false" in your Compose file and restart:
docker compose up -d
Now only existing users can log in. No one else can register.
If you want to invite family members, you can create accounts for them via the admin panel (after setting ADMIN_TOKEN), or temporarily re-enable signups, have them register, then disable again.
Step 7: Configure browser extensions
Install the official Bitwarden browser extension for Chrome, Firefox, Safari, or Edge. Open the extension, click the gear/settings icon, and change the “Server URL” to https://vault.yourdomain.com.
Log in with your email and master password. The extension will connect to your Vaultwarden instance rather than Bitwarden’s cloud servers. Everything else works identically.
Step 8: Configure mobile apps
Install the official Bitwarden app on iOS or Android. Tap the “Self-hosted” option on the login screen and enter your server URL: https://vault.yourdomain.com.
Log in with your credentials. Enable biometric unlock after first login — it’s dramatically more convenient than typing your master password on a phone.
Step 9: Enable the admin panel
Generate a secure admin token:
openssl rand -base64 48
Copy the output and add it to your Compose file:
ADMIN_TOKEN: "paste-the-generated-token-here"
Restart: docker compose up -d
The admin panel is at https://vault.yourdomain.com/admin. Enter the token to access it. From here you can:
- Invite users (bypass the registration flow)
- See all registered users
- Configure global settings
- Run diagnostics
Backup strategy
Your vault is in ~/docker/vaultwarden/data/. Back up this entire directory. The critical file is db.sqlite3 — that’s your passwords.
Simple backup with cron:
# Add to crontab (crontab -e)
0 3 * * * cp ~/docker/vaultwarden/data/db.sqlite3 ~/backups/vaultwarden-$(date +\%Y\%m\%d).sqlite3
For offsite backup, use Syncthing to sync ~/docker/vaultwarden/data/ to another machine. See the Syncthing setup guide.
Keep at least 7 days of backups. If something goes wrong with a sync or update, you want to be able to roll back.
Updating Vaultwarden
Vaultwarden updates are generally safe and quick:
cd ~/docker/vaultwarden
docker compose pull
docker compose up -d
Check Vaultwarden releases for breaking changes before major version updates. The project maintains a changelog with migration notes.
Comparing to Bitwarden cloud
| Feature | Bitwarden Free | Bitwarden Premium ($10/yr) | Vaultwarden Self-Hosted |
|---|---|---|---|
| Passwords, notes, cards | Yes | Yes | Yes |
| Browser extensions | Yes | Yes | Yes |
| Mobile apps | Yes | Yes | Yes |
| TOTP generation | No | Yes | Yes (free) |
| File attachments | No | Yes (1GB) | Yes |
| Organizations/sharing | 2 users free | Paid | Yes (free) |
| Emergency access | No | Yes | Yes (free) |
| Cost | Free | $10/year | Self-hosted (hardware cost only) |
Vaultwarden gives you everything Bitwarden Premium offers, at the cost of running your own infrastructure. If you already have a homelab server, the marginal cost is essentially zero.
Emergency Access
Vaultwarden supports Bitwarden’s Emergency Access feature. You can designate a trusted contact who can request access to your vault in an emergency — useful if you’re the only person in your household managing passwords.
Go to Settings > Emergency Access in the web vault to configure this.
Two-Factor Authentication
Enable 2FA on your Vaultwarden account. Go to Settings > Two-step Login. TOTP (authenticator app) is the easiest option. You can use Bitwarden itself to store the TOTP secret — storing your vault’s 2FA inside your vault is fine for most setups. If you prefer security segmentation, use a separate authenticator app.
What About Bitwarden’s Paid Features?
Vaultwarden implements most of Bitwarden’s premium features for free — TOTP storage, file attachments, emergency access, organization features. The main thing you lose is Bitwarden’s official support and hardware key (FIDO2/WebAuthn) support, which requires the official server. For personal and family use, Vaultwarden covers everything.
The combination of Vaultwarden + Tailscale + Nginx Proxy Manager makes for a genuinely secure, fully functional password management setup that doesn’t rely on anyone else’s servers. For the full security picture, see the Authelia SSO setup guide for adding single sign-on across your homelab. For a deeper look at Vaultwarden’s security model, backups, and trust trade-offs, see the Vaultwarden deep-dive.