You're trusting a SaaS company with every password you own. That's a lot of eggs in one basket. Vaultwarden is an unofficial, lightweight Bitwarden server written in Rust that runs beautifully in Docker. This Vaultwarden Bitwarden self-host guide gets you from zero to a fully operational password manager in 15 minutes—with all the security hardening you need to sleep at night.
Want deeper dives? Check our related guides: Vaultwarden Bitwarden Self-Host: Production Deployment with Docker Compose, NGINX, and PostgreSQL, Vaultwarden Self-Hosting Guide: Deploy Your Own Bitwarden Password Manager in 15 Minutes, and Production Guide: Deploy Vaultwarden with Docker Compose + Caddy on Ubuntu.
What You'll Build
By the end of this guide, you'll have:
- Vaultwarden running in Docker with persistent encrypted storage
- HTTPS via a reverse proxy (Caddy or Traefik)
- SMTP configured for email verification and 2FA notifications
- Admin panel access for user management
- Bitwarden clients (browser, desktop, mobile) connected to your server
- Automated backups of your encrypted vault database
Prerequisites
Before we start, make sure you have:
- Docker 24.0+ and Docker Compose v2 installed
- A Linux server (Ubuntu 22.04/24.04 LTS recommended) with ports 80/443 available
- A domain name with DNS A record pointing to your server
- At least 1GB RAM and 1 CPU core (Vaultwarden is lightweight—512MB works for personal use)
curlfor testing endpoints
Vaultwarden is remarkably efficient. It runs comfortably on a Raspberry Pi or a $5 VPS. The official Bitwarden server requires .NET, SQL Server, and significantly more resources. Vaultwarden replaces all of that with a single Rust binary.
Step 1: Deploy Vaultwarden with Docker Compose
Let's get the core server running. We'll add the reverse proxy and SMTP later.
1.1 Create the Compose File
Create docker-compose.yml:
version: "3.8"
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: unless-stopped
environment:
- WEBSOCKET_ENABLED=true
- SIGNUPS_ALLOWED=false
- INVITATIONS_ALLOWED=false
- ADMIN_TOKEN=***
- DOMAIN=https://vault.yourdomain.com
- SMTP_HOST=smtp.gmail.com
- [email protected]
- SMTP_PORT=587
- SMTP_SECURITY=starttls
- [email protected]
- SMTP_PASSWORD=your-app-password
volumes:
- ./vw-data:/data
ports:
- "80:80"
- "3012:3012" # WebSocket port for live sync
Critical environment variables explained:
WEBSOCKET_ENABLED=true: Enables real-time vault sync across devicesSIGNUPS_ALLOWED=false: Disable public registration after your initial account is createdADMIN_TOKEN: A strong random string for accessing the admin panel at/adminDOMAIN: Must match your public URL exactly. Required for WebAuthn/U2F to work
Generate a secure admin token:
openssl rand -base64 48
1.2 Start the Server
docker compose up -d
Verify it's running:
docker compose ps
curl -s http://localhost | head -n 5
You should see the Vaultwarden login page HTML. But don't create an account yet—we need HTTPS first.
Step 2: Add HTTPS with Caddy
Vaultwarden requires HTTPS for WebAuthn, browser extensions, and mobile apps to work. Caddy makes this trivial with automatic Let's Encrypt certificates.
2.1 Update Compose with Caddy
version: "3.8"
services:
caddy:
image: caddy:2
container_name: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: unless-stopped
environment:
- WEBSOCKET_ENABLED=true
- SIGNUPS_ALLOWED=true
- ADMIN_TOKEN=***
- DOMAIN=https://vault.yourdomain.com
- SMTP_HOST=smtp.gmail.com
- [email protected]
- SMTP_PORT=587
- SMTP_SECURITY=starttls
- [email protected]
- SMTP_PASSWORD=your-app-password
volumes:
- ./vw-data:/data
expose:
- "80"
- "3012"
volumes:
caddy_data:
caddy_config:
2.2 Create the Caddyfile
vault.yourdomain.com {
reverse_proxy vaultwarden:80
# WebSocket support for live sync
@websockets {
header Connection *Upgrade*
header Upgrade websocket
}
reverse_proxy @websockets vaultwarden:3012
}
2.3 Deploy
docker compose down
docker compose up -d
Caddy will automatically request a Let's Encrypt certificate. Within 30 seconds, https://vault.yourdomain.com should be live with a valid certificate.
Step 3: Create Your Account and Configure Security
Now that HTTPS is working, let's set up your vault properly.
3.1 Create the First Account
- Navigate to
https://vault.yourdomain.com - Click Create account
- Use a strong master password (20+ characters, use a passphrase)
- Save your master password somewhere secure and offline
Important: Vaultwarden cannot reset your master password. If you lose it, your vault is permanently inaccessible. This is by design—zero knowledge architecture means even the server admin can't decrypt your data.
3.2 Access the Admin Panel
- Go to
https://vault.yourdomain.com/admin - Enter your
ADMIN_TOKEN
From here you can:
- View and manage all user accounts
- See storage usage and vault statistics
- Configure organization policies
- Disable signups (do this after creating your account)
3.3 Disable Public Registration
After creating your account, lock down registration:
docker compose down
# Edit docker-compose.yml: set SIGNUPS_ALLOWED=false
docker compose up -d
Or use the admin panel: Users → General Settings → Uncheck Allow new signups.
Step 4: Connect Bitwarden Clients
Vaultwarden is fully compatible with official Bitwarden clients. Just point them at your server URL.
4.1 Browser Extension
- Install the Bitwarden browser extension
- Click the gear icon (Settings) → Self-hosted Environment
- Server URL:
https://vault.yourdomain.com - Save, then log in with your email and master password
4.2 Desktop and Mobile Apps
- Open the Bitwarden app
- Before logging in, tap Settings → Self-hosted
- Enter
https://vault.yourdomain.com - Log in normally
4.3 CLI
# Install Bitwarden CLI
npm install -g @bitwarden/cli
# Configure server
bw config server https://vault.yourdomain.com
# Login
bw login [email protected]
# Sync vault
bw sync
Step 5: Enable Two-Factor Authentication
Your master password is the keys to the kingdom. Protect it.
5.1 Enable 2FA on Your Account
- Log into the web vault
- Go to Settings → Security → Master Password → Two-Step Login
- Set up an authenticator app (TOTP) or hardware key (YubiKey)
5.2 Enable 2FA for the Admin Panel
The admin panel uses the ADMIN_TOKEN for access. For extra security, restrict admin access by IP in Caddy:
vault.yourdomain.com/admin* {
@not_allowed not remote_ip YOUR_HOME_IP
respond @not_allowed "Access denied" 403
reverse_proxy vaultwarden:80
}
Step 6: Tips, Troubleshooting, and Production Hardening
6.1 Vaultwarden Won't Start
Check logs for common issues:
docker compose logs vaultwarden | tail -n 50
- Permission denied on /data: Ensure the
vw-datadirectory is writable. Vaultwarden runs as UID 1000 by default - Port already in use: Change the host port mapping if something else binds to 80/443
- SMTP errors: Gmail requires an app-specific password, not your regular password. Enable 2FA on Gmail first
6.2 HTTPS Certificate Issues
- Certificate not valid: Ensure your DNS A record points to the server IP before Caddy starts
- Rate limited by Let's Encrypt: Don't hammer the server. Let's Encrypt allows 50 certificates per domain per week
- Self-signed cert warnings: Vaultwarden clients reject self-signed certs. Use Let's Encrypt or a trusted CA
6.3 WebSocket Sync Not Working
If changes don't sync in real-time across devices:
- Verify
WEBSOCKET_ENABLED=trueis set - Check that your reverse proxy forwards WebSocket connections to port 3012
- Ensure
DOMAINmatches exactly what's in your browser URL bar
6.4 Backup Your Vault
Your encrypted vault lives in ./vw-data. Back it up regularly:
# Create a timestamped backup
tar czf vaultwarden-backup-$(date +%F).tar.gz ./vw-data
# Copy to remote storage (S3, rsync, etc.)
aws s3 cp vaultwarden-backup-$(date +%F).tar.gz s3://your-backup-bucket/
The data is already encrypted at rest—Vaultwarden uses AES-256. But encrypt your backups too for defense in depth:
gpg --symmetric --cipher-algo AES256 vaultwarden-backup-$(date +%F).tar.gz
6.5 Security Hardening Checklist
- Disable signups after creating your account
- Enable 2FA on your vault account (TOTP or hardware key)
- Restrict admin panel by IP or VPN
- Use a strong master password—this is your only decryption key
- Enable fail2ban on your server to prevent brute force login attempts
- Keep Vaultwarden updated:
docker compose pull && docker compose up -d - Monitor logs: Watch for unusual login patterns
6.6 Restore from Backup
# Stop Vaultwarden
docker compose down
# Restore data
rm -rf ./vw-data/*
tar xzf vaultwarden-backup-2026-07-06.tar.gz -C . --strip-components=1
# Restart
docker compose up -d
Wrapping Up
You now have a fully self-hosted password manager that works with every Bitwarden client—browser extensions, desktop apps, mobile apps, and CLI. Your vault is encrypted with your master password, stored on your server, and accessible only to you.
Vaultwarden gives you everything Bitwarden Premium offers—unlimited passwords, attachments, 2FA, organizations, and sharing—without the $10/year subscription. More importantly, your data never leaves your infrastructure.
That said, production deployments for teams—LDAP integration, organization policies, compliance requirements, and high-availability setups—need careful planning.
Need help deploying Vaultwarden for your team, integrating SSO, or building a hardened password management strategy? Get in touch with our team—we've deployed Vaultwarden for clients across healthcare, finance, and SaaS. We'll get your password infrastructure right.