Security intermediate ⏱ 30 minutes

Vaultwarden: Self-Hosted Password Manager

Secure password management with Bitwarden compatibility. Team sharing, 2FA, and complete data ownership.

By homelabbing.io • 2025-12-16
#vaultwarden#passwords#security#self-hosted#docker

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:

  1. Vaultwarden Server: Core password vault backend
  2. Reverse Proxy: Caddy for automatic HTTPS
  3. Database: SQLite (default) or PostgreSQL for larger deployments
  4. Backup System: Automated encrypted backups
  5. 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:

  1. Replace vault.yourdomain.com with your actual domain
  2. Generate admin token:
    openssl rand -base64 48
  3. Set SIGNUPS_ALLOWED: "false" after creating your account
  4. 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

  1. Click “Create account”
  2. Enter email address
  3. 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
  4. Confirm password
  5. 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:

  1. Enable 2FA on your Google account
  2. Generate an App Password
  3. 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:

  1. Install “Bitwarden Password Manager” from Chrome Web Store
  2. Click extension icon
  3. Settings (gear icon)
  4. Server URL: https://vault.yourdomain.com
  5. Save
  6. Log in with your credentials

Firefox:

  1. Install “Bitwarden Password Manager” from Firefox Add-ons
  2. Follow same steps as Chrome

Safari:

  1. Install from Mac App Store
  2. Enable in Safari Extensions preferences
  3. Configure server URL

Mobile Apps

iOS (iPhone/iPad):

  1. Install “Bitwarden Password Manager” from App Store
  2. Before logging in, tap Settings (gear icon)
  3. Self-hosted Environment
  4. Server URL: https://vault.yourdomain.com
  5. Save
  6. Log in

Android:

  1. Install “Bitwarden Password Manager” from Play Store
  2. Tap three-dot menu Settings
  3. Self-hosted Environment
  4. Server URL: https://vault.yourdomain.com
  5. Save
  6. Log in

Desktop Applications

Windows/macOS/Linux:

  1. Download from bitwarden.com/download
  2. Install and launch
  3. File Settings
  4. Self-hosted Environment
  5. Server URL: https://vault.yourdomain.com
  6. Save and restart
  7. Log in

Using Vaultwarden

Adding Passwords

Via Browser Extension:

  1. Navigate to a website
  2. Click Bitwarden extension
  3. Add (+ icon) New Item
  4. Type: Login
  5. Name: Website name
  6. Username: your username
  7. Password: Generate or enter
  8. URL: Auto-filled
  9. Save

Via Web Vault:

  1. Log into web vault
  2. Click “New” (+ icon)
  3. Fill in details
  4. 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:

  1. Web Vault Settings Folders
  2. New Folder
  3. Name: “Work”, “Personal”, “Banking”, etc.

Assign items to folders:

  1. Edit item
  2. Folder dropdown
  3. Select folder
  4. 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:

  1. Edit item
  2. Attachments New Attachment
  3. Choose file (max 100MB per file, 1GB default user limit)
  4. Upload

Use for:

  • Scanned documents
  • PDF bank statements
  • Passport/ID scans
  • Recovery codes
  • SSL certificates

Organizations and Sharing

Creating an Organization

  1. Web Vault New Organization
  2. Organization Name: “Family”, “Team”, etc.
  3. Billing Email: your email
  4. Plan: Free (Vaultwarden includes all features)
  5. Create

Managing Members

Invite Users:

  1. Organization Manage Members
  2. Invite User
  3. Enter email
  4. Select Collections
  5. 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:

  1. Organization Manage Collections
  2. New Collection
  3. Name: “Shared Passwords”, “Netflix”, etc.
  4. Assign access to users
  5. Save

Sharing Passwords

Add Item to Organization:

  1. Create or edit item
  2. Ownership: Select your organization
  3. Collection: Assign to collection
  4. Save

Members with collection access can now see this item

Emergency Access

Grant trusted contacts emergency vault access:

Setup Emergency Access:

  1. Settings Emergency Access
  2. Add Contact
  3. Enter email (must have Vaultwarden account)
  4. Wait time: 7-90 days
  5. Access level: View or Takeover
  6. 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:

  1. Settings Two-step Login Providers
  2. Authenticator App Setup
  3. Scan QR code with:
    • Authy (recommended, cloud backup)
    • Google Authenticator
    • Microsoft Authenticator
  4. Enter 6-digit code to verify
  5. Save recovery code

Hardware Keys:

  1. Settings Two-step Login Providers
  2. FIDO U2F or WebAuthn
  3. Insert key and follow prompts
  4. 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:

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

  1. Verify email and master password
  2. Check server URL in client settings
  3. Clear browser cache/cookies
  4. Check vaultwarden logs:
    docker-compose logs vaultwarden | grep -i login

Issue: Invitations not working

  1. Verify SMTP settings in admin panel
  2. Test email sending from admin panel
  3. 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:

  1. iPhone Settings Passwords AutoFill Passwords
  2. Enable AutoFill Passwords
  3. Select Bitwarden
  4. Test by opening Safari and trying to log in

Android Autofill

Enable autofill service:

  1. Settings System Languages & input Advanced Autofill service
  2. Select Bitwarden
  3. Test in Chrome or other apps

Biometric Unlock

Enable fingerprint/Face ID:

iOS:

  1. Bitwarden app Settings Security Unlock with Face ID/Touch ID
  2. Enable

Android:

  1. Bitwarden app Settings Unlock with Biometrics
  2. 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:

  1. Review user list monthly
  2. Check for inactive users
  3. Audit organization memberships
  4. Review access logs
  5. Update Docker images monthly
  6. Verify backups are working
  7. 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: