Vaultwarden: Self-Hosted Password Manager
Secure password management with Bitwarden compatibility. Team sharing, 2FA, and complete data ownership.
Introduction
Vaultwarden is a lightweight, unofficial Bitwarden server implementation written in Rust. It provides all the features of Bitwarden Premium for free, including two-factor authentication, collections, file attachments, and organization support. By self-hosting Vaultwarden, you gain complete control over your password vault while maintaining compatibility with all official Bitwarden clients.
By the end of this guide, you’ll have a production-ready Vaultwarden installation that:
- Stores passwords, secure notes, and files with end-to-end encryption
- Works with all Bitwarden clients (browser extensions, mobile apps, desktop apps)
- Supports multiple users and organizations for team password sharing
- Includes automated HTTPS with Let’s Encrypt
- Features comprehensive backup and disaster recovery
- Implements advanced security with 2FA and fail2ban protection
Prerequisites
Before starting, ensure you have:
- A Linux server (VM, VPS, or bare metal) with at least 512MB RAM
- Docker and Docker Compose installed
- A domain name pointing to your server (e.g., vault.yourdomain.com)
- Port 80 and 443 accessible from the internet (for Let’s Encrypt validation)
- Root or sudo access
- At least 10GB free disk space
- Basic understanding of Docker and DNS
Why Self-Host Your Password Manager?
Privacy and Control
When you self-host Vaultwarden:
- Your passwords never leave your infrastructure
- No third-party has access to your encrypted vault
- You control backups, retention, and disaster recovery
- Complete audit trail of all access and changes
Cost Savings
Vaultwarden provides for free:
- Unlimited vault items
- File attachments (up to 1GB per file)
- Organization support for teams
- Premium 2FA methods (U2F, Duo, YubiKey)
- Priority support features
Features
All Bitwarden Premium features:
- Password generator with customizable rules
- Secure password sharing via organizations
- File storage and attachments
- Multiple 2FA options
- Emergency access
- Vault health reports
Architecture Overview
Our deployment consists of:
- Vaultwarden Server: Core password vault backend
- Reverse Proxy: Caddy for automatic HTTPS
- Database: SQLite (default) or PostgreSQL for larger deployments
- Backup System: Automated encrypted backups
- Optional: Fail2ban for brute-force protection
Data flow:
- Clients connect via HTTPS to reverse proxy
- Proxy forwards to Vaultwarden container
- Vaultwarden encrypts/decrypts vault data
- Data stored in SQLite database
- Automated backups to secure location
Directory Structure Setup
Create the necessary directory structure:
mkdir -p ~/vaultwarden/{data,caddy,backups,scripts}
cd ~/vaultwarden Create subdirectories:
mkdir -p caddy/{config,data}
mkdir -p data/{attachments,sends} Docker Compose Configuration
Create a docker-compose.yml file:
version: '3.8'
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: unless-stopped
environment:
DOMAIN: "https://vault.yourdomain.com"
SIGNUPS_ALLOWED: "false"
INVITATIONS_ALLOWED: "true"
SHOW_PASSWORD_HINT: "false"
WEBSOCKET_ENABLED: "true"
WEB_VAULT_ENABLED: "true"
LOG_FILE: "/data/vaultwarden.log"
LOG_LEVEL: "info"
EXTENDED_LOGGING: "true"
SMTP_HOST: "smtp.gmail.com"
SMTP_FROM: "[email protected]"
SMTP_PORT: "587"
SMTP_SECURITY: "starttls"
SMTP_USERNAME: "[email protected]"
SMTP_PASSWORD: "your-app-password"
ADMIN_TOKEN: "GENERATE_WITH_openssl_rand_base64_48"
YUBICO_CLIENT_ID: ""
YUBICO_SECRET_KEY: ""
DUO_IKEY: ""
DUO_SKEY: ""
DUO_HOST: ""
ICON_CACHE_TTL: "2592000"
ICON_CACHE_NEGTTL: "259200"
ATTACHMENT_LIMIT: "100000"
USER_ATTACHMENT_LIMIT: "1048576"
ORG_ATTACHMENT_LIMIT: "1048576"
SENDS_ALLOWED: "true"
EMERGENCY_ACCESS_ALLOWED: "true"
PASSWORD_HINTS_ALLOWED: "false"
DISABLE_2FA_REMEMBER: "false"
volumes:
- ./data:/data
ports:
- "8080:80"
- "3012:3012"
networks:
- vaultwarden_net
caddy:
image: caddy:latest
container_name: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
- ./caddy/config:/config
- ./caddy/data:/data
networks:
- vaultwarden_net
depends_on:
- vaultwarden
networks:
vaultwarden_net:
driver: bridge Important Configuration Notes:
- Replace
vault.yourdomain.comwith your actual domain - Generate admin token:
openssl rand -base64 48 - Set
SIGNUPS_ALLOWED: "false"after creating your account - Configure SMTP for email notifications (optional but recommended)
Caddy Reverse Proxy Configuration
Create a caddy/Caddyfile:
vault.yourdomain.com {
encode gzip
# Vaultwarden web interface
reverse_proxy vaultwarden:80 {
header_up X-Real-IP {remote_host}
}
# WebSocket support for live sync
@websocket {
path /notifications/hub
}
reverse_proxy @websocket vaultwarden:3012
# Security headers
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
X-XSS-Protection "1; mode=block"
Referrer-Policy "same-origin"
}
# Logging
log {
output file /data/access.log
format json
}
} Key features:
- Automatic HTTPS with Let’s Encrypt
- WebSocket support for real-time sync
- Security headers for hardening
- Gzip compression for faster loading
DNS Configuration
Point your domain to your server’s IP address:
A Record:
vault.yourdomain.com -> YOUR-SERVER-IP Verify DNS propagation:
dig vault.yourdomain.com +short
nslookup vault.yourdomain.com Wait for DNS to propagate (can take up to 48 hours, usually much faster).
Starting Vaultwarden
Start all services:
docker-compose up -d Verify containers are running:
docker-compose ps Check logs:
docker-compose logs -f vaultwarden
docker-compose logs -f caddy Initial Setup and Account Creation
Access Web Vault
Navigate to https://vault.yourdomain.com
You should see the Bitwarden web vault interface with automatic HTTPS.
Create Your Account
- Click “Create account”
- Enter email address
- Create a strong master password (minimum 12 characters)
- Use a mix of uppercase, lowercase, numbers, and symbols
- This is the ONLY password you need to remember
- Write it down and store securely
- Consider using dice-generated passphrases
- Confirm password
- Click “Submit”
CRITICAL: Your master password cannot be recovered. If you lose it, you lose access to your vault.
Disable Public Signups
After creating your account, prevent unauthorized signups:
Edit docker-compose.yml:
SIGNUPS_ALLOWED: "false" Restart:
docker-compose restart vaultwarden Admin Panel Configuration
Access the admin panel at https://vault.yourdomain.com/admin
Use the admin token you generated earlier.
General Settings
Domain URL: Verify set to https://vault.yourdomain.com
Signups:
- Signups allowed: Disabled
- Invitations allowed: Enabled (for adding new users)
- Password hints: Disabled (security risk)
Advanced Settings:
- Icon cache TTL: 2592000 (30 days)
- Disable 2FA remember: Keep enabled for security
SMTP Configuration
Configure email for invitations and notifications:
Gmail Example:
- Enable 2FA on your Google account
- Generate an App Password
- Use settings:
- Host: smtp.gmail.com
- Port: 587
- Security: STARTTLS
- Username: [email protected]
- Password: app-password
Test email:
# From admin panel, send test email Two-Factor Authentication (2FA)
Vaultwarden supports multiple 2FA methods:
TOTP (Time-based One-Time Password):
- Free, no configuration needed
- Use apps like Authy, Google Authenticator, Microsoft Authenticator
Duo Security:
- Configure DUO_IKEY, DUO_SKEY, DUO_HOST in docker-compose.yml
YubiKey OTP:
- Configure YUBICO_CLIENT_ID and YUBICO_SECRET_KEY
- Supports multiple YubiKeys per account
U2F/WebAuthn:
- Hardware security keys (YubiKey, Titan, etc.)
- No server configuration needed
Client Setup
Browser Extensions
Chrome/Brave/Edge:
- Install “Bitwarden Password Manager” from Chrome Web Store
- Click extension icon
- Settings (gear icon)
- Server URL:
https://vault.yourdomain.com - Save
- Log in with your credentials
Firefox:
- Install “Bitwarden Password Manager” from Firefox Add-ons
- Follow same steps as Chrome
Safari:
- Install from Mac App Store
- Enable in Safari Extensions preferences
- Configure server URL
Mobile Apps
iOS (iPhone/iPad):
- Install “Bitwarden Password Manager” from App Store
- Before logging in, tap Settings (gear icon)
- Self-hosted Environment
- Server URL:
https://vault.yourdomain.com - Save
- Log in
Android:
- Install “Bitwarden Password Manager” from Play Store
- Tap three-dot menu Settings
- Self-hosted Environment
- Server URL:
https://vault.yourdomain.com - Save
- Log in
Desktop Applications
Windows/macOS/Linux:
- Download from bitwarden.com/download
- Install and launch
- File Settings
- Self-hosted Environment
- Server URL:
https://vault.yourdomain.com - Save and restart
- Log in
Using Vaultwarden
Adding Passwords
Via Browser Extension:
- Navigate to a website
- Click Bitwarden extension
- Add (+ icon) New Item
- Type: Login
- Name: Website name
- Username: your username
- Password: Generate or enter
- URL: Auto-filled
- Save
Via Web Vault:
- Log into web vault
- Click “New” (+ icon)
- Fill in details
- Save
Password Generator
Use the built-in generator for strong passwords:
Options:
- Length: 14-32 characters (20+ recommended)
- Uppercase (A-Z)
- Lowercase (a-z)
- Numbers (0-9)
- Special Characters (!@#$%^&*)
- Minimum numbers: 1
- Minimum special: 1
- Avoid ambiguous characters
Passphrase Generator:
- Number of words: 4-7
- Word separator: -
- Capitalize: Yes
- Include number: Yes
Organizing with Folders
Create folders for organization:
- Web Vault Settings Folders
- New Folder
- Name: “Work”, “Personal”, “Banking”, etc.
Assign items to folders:
- Edit item
- Folder dropdown
- Select folder
- Save
Secure Notes and Cards
Secure Notes:
- Store wifi passwords, recovery codes, software licenses
- Field type: “Secure Note”
- Custom fields for structured data
Payment Cards:
- Credit card numbers (encrypted)
- Expiration dates
- CVV codes (optional)
- Billing address
Identities:
- Full name, address, phone
- Multiple identities for different personas
- Auto-fill for forms
File Attachments
Attach files to vault items:
- Edit item
- Attachments New Attachment
- Choose file (max 100MB per file, 1GB default user limit)
- Upload
Use for:
- Scanned documents
- PDF bank statements
- Passport/ID scans
- Recovery codes
- SSL certificates
Organizations and Sharing
Creating an Organization
- Web Vault New Organization
- Organization Name: “Family”, “Team”, etc.
- Billing Email: your email
- Plan: Free (Vaultwarden includes all features)
- Create
Managing Members
Invite Users:
- Organization Manage Members
- Invite User
- Enter email
- Select Collections
- Send Invite
User Types:
- Owner: Full control
- Admin: Manage users and collections
- User: Access assigned collections
- Manager: Manage collections and users within collections
Collections
Group shared items:
- Organization Manage Collections
- New Collection
- Name: “Shared Passwords”, “Netflix”, etc.
- Assign access to users
- Save
Sharing Passwords
Add Item to Organization:
- Create or edit item
- Ownership: Select your organization
- Collection: Assign to collection
- Save
Members with collection access can now see this item
Emergency Access
Grant trusted contacts emergency vault access:
Setup Emergency Access:
- Settings Emergency Access
- Add Contact
- Enter email (must have Vaultwarden account)
- Wait time: 7-90 days
- Access level: View or Takeover
- Send Invite
How It Works:
- Contact requests emergency access
- Wait period begins (you can approve immediately)
- After wait period, contact gains access
- You receive email notifications
Security Best Practices
Master Password Security
Requirements:
- Minimum 12 characters (20+ recommended)
- Mix of character types
- Unique (never used elsewhere)
- Memorable but complex
Passphrase Method (Recommended):
- 4-6 random words:
correct-horse-battery-staple-sunrise-42 - Easy to remember, hard to crack
- Use dice or word list for randomness
Storage:
- Write down on paper, store in safe
- Share with trusted family member
- Consider password manager master password card
- NEVER store digitally
Enable Two-Factor Authentication
Setup TOTP:
- Settings Two-step Login Providers
- Authenticator App Setup
- Scan QR code with:
- Authy (recommended, cloud backup)
- Google Authenticator
- Microsoft Authenticator
- Enter 6-digit code to verify
- Save recovery code
Hardware Keys:
- Settings Two-step Login Providers
- FIDO U2F or WebAuthn
- Insert key and follow prompts
- Add backup key (strongly recommended)
Recommended Setup:
- Primary: TOTP app
- Backup: Hardware key
- Emergency: Recovery code (stored offline)
Vault Timeout Settings
Configure auto-lock:
Browser Extension:
- Settings Options Vault Timeout
- Options: Immediate, 1 minute, 5 minutes, 15 minutes, 1 hour, Never
- Recommended: 5-15 minutes
Mobile Apps:
- Settings Vault Timeout
- Additional option: On App Restart
- Biometric unlock (Face ID, Touch ID, Fingerprint)
SSL/TLS Security
Verify HTTPS is working:
# Test SSL configuration
openssl s_client -connect vault.yourdomain.com:443 -servername vault.yourdomain.com
# Check certificate
curl -vI https://vault.yourdomain.com 2>&1 | grep -i "certificate" SSL Labs Test:
- Visit: https://www.ssllabs.com/ssltest/
- Enter: vault.yourdomain.com
- Should achieve A+ rating
Firewall Configuration
Restrict access to Vaultwarden:
# Allow HTTPS from anywhere
sudo ufw allow 443/tcp
sudo ufw allow 80/tcp
# Block direct access to Vaultwarden port
sudo ufw deny 8080/tcp
# Enable firewall
sudo ufw enable Fail2Ban Protection
Install fail2ban to prevent brute force:
sudo apt install fail2ban Create /etc/fail2ban/filter.d/vaultwarden.conf:
[INCLUDES]
before = common.conf
[Definition]
failregex = ^.*Username or password is incorrect. Try again. IP: <HOST>. Username:.*$
ignoreregex = Create /etc/fail2ban/jail.d/vaultwarden.local:
[vaultwarden]
enabled = true
port = 80,443,8081
filter = vaultwarden
action = iptables-allports[name=vaultwarden, chain=FORWARD]
logpath = /path/to/vaultwarden/data/vaultwarden.log
maxretry = 3
bantime = 14400
findtime = 14400 Restart fail2ban:
sudo systemctl restart fail2ban
sudo fail2ban-client status vaultwarden Backup Procedures
Automated Backup Script
Create a backup script at scripts/backup-vaultwarden.sh:
#!/bin/bash
BACKUP_DIR="./backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="vaultwarden_backup_$TIMESTAMP"
DATA_DIR="./data"
# Create backup directory
mkdir -p "$BACKUP_DIR"
echo "Starting Vaultwarden backup..."
# Stop container for consistent backup
docker-compose stop vaultwarden
# Backup database and data
echo "Backing up data directory..."
tar -czf "$BACKUP_DIR/$BACKUP_NAME.tar.gz" -C . data/
# Backup docker-compose configuration
cp docker-compose.yml "$BACKUP_DIR/docker-compose_$TIMESTAMP.yml"
# Start container
docker-compose start vaultwarden
# Encrypt backup
echo "Encrypting backup..."
gpg --symmetric --cipher-algo AES256 "$BACKUP_DIR/$BACKUP_NAME.tar.gz"
rm "$BACKUP_DIR/$BACKUP_NAME.tar.gz"
# Keep only last 30 backups
echo "Cleaning old backups (keeping last 30)..."
cd "$BACKUP_DIR"
ls -t vaultwarden_backup_*.tar.gz.gpg | tail -n +31 | xargs -r rm
echo "Backup completed: $BACKUP_DIR/$BACKUP_NAME.tar.gz.gpg"
echo "Backup size: $(du -h $BACKUP_DIR/$BACKUP_NAME.tar.gz.gpg | cut -f1)" Make executable:
chmod +x scripts/backup-vaultwarden.sh Set up GPG encryption:
# Generate GPG key
gpg --full-generate-key
# Or use passphrase-only encryption (simpler)
# The script above uses symmetric encryption Automated Backups with Cron
crontab -e Add daily backup at 2 AM:
0 2 * * * cd /path/to/vaultwarden && ./scripts/backup-vaultwarden.sh >> ./backups/backup.log 2>&1 Off-site Backup
Sync to remote server:
# Using rsync
rsync -avz --delete ./backups/ user@remote-server:/backups/vaultwarden/
# Using rclone (supports cloud storage)
rclone sync ./backups/ remote:vaultwarden-backups/ Automated cloud backup:
#!/bin/bash
# Add to backup script
# Upload to AWS S3
aws s3 cp "$BACKUP_DIR/$BACKUP_NAME.tar.gz.gpg" s3://your-bucket/vaultwarden/
# Or Backblaze B2
b2 upload-file your-bucket "$BACKUP_DIR/$BACKUP_NAME.tar.gz.gpg" vaultwarden/$BACKUP_NAME.tar.gz.gpg Restore Procedure
Create restore script at scripts/restore-vaultwarden.sh:
#!/bin/bash
if [ -z "$1" ]; then
echo "Usage: $0 backup_file.tar.gz.gpg"
exit 1
fi
BACKUP_FILE="$1"
echo "Restoring from $BACKUP_FILE..."
# Decrypt backup
echo "Decrypting backup..."
gpg --decrypt "$BACKUP_FILE" > /tmp/vaultwarden_restore.tar.gz
# Stop container
echo "Stopping Vaultwarden..."
docker-compose down
# Backup current state
echo "Backing up current state..."
mv data data.bak_$(date +%Y%m%d_%H%M%S)
# Extract backup
echo "Restoring data..."
tar -xzf /tmp/vaultwarden_restore.tar.gz
# Clean up
rm /tmp/vaultwarden_restore.tar.gz
# Start container
echo "Starting Vaultwarden..."
docker-compose up -d
echo "Restore completed successfully!" Make executable:
chmod +x scripts/restore-vaultwarden.sh Monitoring and Maintenance
Health Check Script
Create monitoring script at scripts/healthcheck.sh:
#!/bin/bash
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
echo "=== Vaultwarden Health Check ==="
echo ""
# Check containers
echo -n "Vaultwarden container: "
if docker ps | grep -q vaultwarden; then
echo -e "${GREEN}Running${NC}"
else
echo -e "${RED}Not running${NC}"
fi
echo -n "Caddy container: "
if docker ps | grep -q caddy; then
echo -e "${GREEN}Running${NC}"
else
echo -e "${RED}Not running${NC}"
fi
# Test HTTPS
echo -n "HTTPS connectivity: "
if curl -s -o /dev/null -w "%{http_code}" https://vault.yourdomain.com | grep -q 200; then
echo -e "${GREEN}Working${NC}"
else
echo -e "${RED}Failed${NC}"
fi
# Check disk space
echo ""
echo "Disk usage:"
df -h | grep -E "Filesystem|/mnt|/$"
# Check database size
echo ""
echo "Database size:"
du -sh data/db.sqlite3
# Check attachment storage
echo "Attachment storage:"
du -sh data/attachments/
# Check logs for errors
echo ""
echo "Recent errors in logs:"
docker-compose logs vaultwarden --tail=100 | grep -i error | tail -5 Make executable:
chmod +x scripts/healthcheck.sh Update Procedure
Create update script at scripts/update-vaultwarden.sh:
#!/bin/bash
echo "=== Vaultwarden Update ==="
echo ""
# Backup before update
echo "Creating pre-update backup..."
./scripts/backup-vaultwarden.sh
# Pull latest images
echo "Pulling latest Docker images..."
docker-compose pull
# Restart containers
echo "Restarting containers with new images..."
docker-compose up -d
# Check status
echo ""
echo "Checking container status..."
docker-compose ps
echo ""
echo "Update completed!"
echo "Check logs for any errors:"
echo "docker-compose logs -f" Make executable:
chmod +x scripts/update-vaultwarden.sh Schedule monthly updates:
crontab -e Add:
0 3 1 * * cd /path/to/vaultwarden && ./scripts/update-vaultwarden.sh >> ./backups/update.log 2>&1 Advanced Configuration
PostgreSQL Database
For larger deployments, use PostgreSQL:
Add to docker-compose.yml:
postgres:
image: postgres:15-alpine
container_name: vaultwarden_db
restart: unless-stopped
environment:
POSTGRES_DB: vaultwarden
POSTGRES_USER: vaultwarden
POSTGRES_PASSWORD: SECURE_PASSWORD_HERE
volumes:
- ./postgres:/var/lib/postgresql/data
networks:
- vaultwarden_net
vaultwarden:
# ... existing config ...
environment:
DATABASE_URL: "postgresql://vaultwarden:SECURE_PASSWORD_HERE@postgres:5432/vaultwarden"
depends_on:
- postgres Custom Domain Per Organization
Support multiple organizations with subdomains:
# Caddyfile
vault.yourdomain.com {
reverse_proxy vaultwarden:80
}
org1.yourdomain.com {
reverse_proxy vaultwarden:80
}
org2.yourdomain.com {
reverse_proxy vaultwarden:80
} Reverse Proxy Behind NAT
If behind NAT without port forwarding, use Cloudflare Tunnel:
cloudflared:
image: cloudflare/cloudflared:latest
command: tunnel --no-autoupdate run
environment:
TUNNEL_TOKEN: YOUR_TUNNEL_TOKEN
networks:
- vaultwarden_net Troubleshooting
Common Issues
Issue: Cannot access web vault
# Check container status
docker-compose ps
# Check logs
docker-compose logs vaultwarden
docker-compose logs caddy
# Verify DNS
dig vault.yourdomain.com +short
# Test direct access (bypass Caddy)
curl http://localhost:8080 Issue: SSL certificate errors
# Check Caddy logs
docker-compose logs caddy | grep -i error
# Verify ports 80/443 are accessible
sudo netstat -tlnp | grep -E ":(80|443)"
# Test Let's Encrypt validation
curl http://vault.yourdomain.com/.well-known/acme-challenge/test Issue: Login failing
- Verify email and master password
- Check server URL in client settings
- Clear browser cache/cookies
- Check vaultwarden logs:
docker-compose logs vaultwarden | grep -i login
Issue: Invitations not working
- Verify SMTP settings in admin panel
- Test email sending from admin panel
- Check SMTP logs:
docker-compose logs vaultwarden | grep -i smtp
Database Maintenance
Check database integrity:
docker exec vaultwarden sqlite3 /data/db.sqlite3 "PRAGMA integrity_check;" Vacuum database (reclaim space):
docker exec vaultwarden sqlite3 /data/db.sqlite3 "VACUUM;" Backup database only:
docker exec vaultwarden sqlite3 /data/db.sqlite3 ".backup '/data/db_backup.sqlite3'" Mobile Device Configuration
iOS Autofill
Enable password autofill:
- iPhone Settings Passwords AutoFill Passwords
- Enable AutoFill Passwords
- Select Bitwarden
- Test by opening Safari and trying to log in
Android Autofill
Enable autofill service:
- Settings System Languages & input Advanced Autofill service
- Select Bitwarden
- Test in Chrome or other apps
Biometric Unlock
Enable fingerprint/Face ID:
iOS:
- Bitwarden app Settings Security Unlock with Face ID/Touch ID
- Enable
Android:
- Bitwarden app Settings Unlock with Biometrics
- Enable
Performance Optimization
Icon Cache
Icons are cached for faster loading:
ICON_CACHE_TTL: "2592000" # 30 days
ICON_CACHE_NEGTTL: "259200" # 3 days for failed icons Attachment Limits
Adjust based on your storage:
ATTACHMENT_LIMIT: "100000" # 100MB per attachment
USER_ATTACHMENT_LIMIT: "1048576" # 1GB per user
ORG_ATTACHMENT_LIMIT: "1048576" # 1GB per organization WebSocket for Real-time Sync
Ensure WebSocket is enabled:
WEBSOCKET_ENABLED: "true" In Caddyfile:
@websocket {
path /notifications/hub
}
reverse_proxy @websocket vaultwarden:3012 Security Hardening
Disable Password Hints
Always disable:
SHOW_PASSWORD_HINT: "false"
PASSWORD_HINTS_ALLOWED: "false" Restrict Admin Panel Access
Limit admin panel to local network:
Edit docker-compose.yml:
ADMIN_TOKEN: "your-token"
IP_HEADER: "X-Real-IP" Add to Caddyfile:
@admin {
path /admin*
not remote_ip 192.168.1.0/24
}
respond @admin 403 Regular Security Audits
Schedule regular security reviews:
- Review user list monthly
- Check for inactive users
- Audit organization memberships
- Review access logs
- Update Docker images monthly
- Verify backups are working
- Test restore procedure quarterly
Conclusion
You now have a fully functional self-hosted password manager with:
- Complete control over your password vault
- End-to-end encryption for all data
- Support for all Bitwarden clients
- Organization support for team sharing
- Automated HTTPS with Let’s Encrypt
- Comprehensive backup and disaster recovery
- Advanced security with 2FA and fail2ban
- Mobile app integration with biometric unlock
Vaultwarden provides all the features of Bitwarden Premium while maintaining complete privacy and control over your sensitive data.
Next Steps
Consider these enhancements:
- Set up high availability with multiple Vaultwarden instances
- Implement database replication with PostgreSQL
- Configure monitoring with Prometheus and Grafana
- Set up alerts for failed logins
- Implement geographic backups
- Add LDAP/Active Directory integration for organizations
- Configure custom email templates
- Set up SSO with OAuth2/OpenID Connect
For support and updates, visit:
- Vaultwarden GitHub: https://github.com/dani-garcia/vaultwarden
- Vaultwarden Wiki: https://github.com/dani-garcia/vaultwarden/wiki
- Bitwarden Help Center: https://bitwarden.com/help/