Vaultwarden Setup Guide: Self-Host Your Own Bitwarden Password Manager


Vaultwarden Setup Guide: Self-Host Your Own Bitwarden Password Manager

Your passwords are the keys to your entire digital life. And right now, they probably sit on someone else’s server. LastPass has been breached. 1Password costs $36/year and keeps raising prices. Bitwarden Cloud is solid, but you still trust a third party with your most sensitive data.

There is another option: run your own password manager. Vaultwarden makes that surprisingly easy. It is a lightweight, community-built implementation of the Bitwarden server API written in Rust, and it runs on hardware as small as a Raspberry Pi. You get full compatibility with every official Bitwarden client — browser extensions, desktop apps, mobile apps — while keeping every password encrypted on your own machine.

This guide walks you through a complete vaultwarden setup from zero to a production-ready, backed-up, HTTPS-secured password vault that syncs across all your devices.

What Is Vaultwarden (And Why Not Official Bitwarden?)

Vaultwarden (formerly known as bitwarden_rs) is an unofficial Bitwarden-compatible server written in Rust by Daniel Garcia. It implements the Bitwarden API, which means all official Bitwarden clients connect to it without modification. You simply point the client at your server URL instead of bitwarden.com.

The key differences from the official Bitwarden server:

  • Resource usage: The official Bitwarden server requires Microsoft SQL Server and multiple Docker containers consuming 2+ GB of RAM. Vaultwarden uses SQLite by default and runs in a single container with under 50 MB of RAM at idle.
  • Premium features included: Vaultwarden unlocks Bitwarden premium features for free — TOTP authenticator, file attachments, emergency access, and vault health reports.
  • Simplicity: One Docker image. One volume. One environment variable file. That is the entire deployment.
  • Active development: The project is actively maintained with regular releases. As of early 2026, the latest version is 1.35.2, which includes OpenID Connect SSO support and an updated web vault.

Vaultwarden is not a fork of Bitwarden. It is a clean-room reimplementation of the server API. The official Bitwarden clients do not know or care which server they are talking to.

Why Self-Host Your Passwords?

If you use a cloud password manager, you trust that provider to store your encrypted vault securely, remain in business, not change their pricing or terms, and not suffer a breach that exposes vault metadata or encrypted blobs.

A self-hosted password manager eliminates those dependencies:

  • Full data ownership: Your encrypted vault lives on your hardware. No third party can access it, lose it, or hold it hostage.
  • No subscription fees: Vaultwarden is free and open source. Your only cost is the electricity to run the server.
  • No feature gates: Every Bitwarden premium feature works out of the box without paying for a premium license.
  • Network-level control: You decide who can reach your vault — local network only, VPN-only, or public with hardened access controls.
  • Privacy: No telemetry, no analytics, no metadata collection. Your password usage patterns stay private.

The tradeoff is real: you are responsible for uptime, backups, and security updates. This guide covers all three.

Password Manager Comparison

Before diving into setup, here is how Vaultwarden stacks up against the major options:

FeatureVaultwardenBitwarden CloudLastPass1Password
CostFree (self-hosted)Free tier / $10/yr premium$36/year$36/year
Data locationYour serverBitwarden’s cloudLastPass cloud1Password cloud
Open sourceYes (GPL-3.0)Server is open sourceNoNo
TOTP authenticatorIncludedPremium onlyPremium onlyIncluded
File attachmentsIncludedPremium onlyPremium onlyIncluded
Passkey supportYesYesYesYes
Emergency accessIncludedPremium onlyPremium onlyIncluded
Browser extensionsBitwarden officialBitwarden officialProprietaryProprietary
Mobile appsBitwarden officialBitwarden officialProprietaryProprietary
Offline accessYesYesYesYes
RAM usage~50 MB~2 GB (self-hosted)N/A (cloud)N/A (cloud)
Breach historyN/A (self-hosted)NoneMultiple incidentsNone
SSO/OIDCYes (v1.35+)Enterprise onlyEnterprise onlyEnterprise only

The standout advantage of Vaultwarden is the combination of zero cost, full feature set, and complete data control. If you are already running a homelab or VPS, adding Vaultwarden takes about 15 minutes.

Hardware Requirements

Vaultwarden is one of the lightest self-hosted applications you will ever run:

  • CPU: Any x86_64 or ARM64 processor. A Raspberry Pi 3 or newer works fine.
  • RAM: 50 MB at idle, up to 100 MB under active use. Even a 512 MB system has plenty of headroom.
  • Storage: The SQLite database for a personal vault with hundreds of entries is typically under 10 MB. Budget 1 GB for attachments and growth.
  • Network: Needs to be reachable by your devices. Local network is sufficient if you only use passwords at home. For mobile sync everywhere, you need either a public IP with a domain or a VPN like Tailscale or WireGuard.

If you have any Linux machine running Docker, you have enough hardware for Vaultwarden.

Docker Compose Setup

Create a directory for your Vaultwarden deployment:

mkdir -p ~/docker/vaultwarden
cd ~/docker/vaultwarden

Create the docker-compose.yml file:

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    environment:
      - DOMAIN=https://vault.yourdomain.com
      - SIGNUPS_ALLOWED=true
      - ADMIN_TOKEN=${ADMIN_TOKEN}
      - SMTP_HOST=smtp.gmail.com
      - SMTP_FROM=vault@yourdomain.com
      - SMTP_PORT=587
      - SMTP_SECURITY=starttls
      - SMTP_USERNAME=${SMTP_USERNAME}
      - SMTP_PASSWORD=${SMTP_PASSWORD}
      - LOG_FILE=/data/vaultwarden.log
      - LOG_LEVEL=warn
      - TZ=America/New_York
    volumes:
      - ./vw-data:/data
    ports:
      - "127.0.0.1:8080:80"

Create the .env file with your secrets:

# Generate a secure admin token using argon2 hash
# Run this command and paste the output as ADMIN_TOKEN:
# docker run --rm vaultwarden/server /vaultwarden hash --preset owasp

ADMIN_TOKEN='$argon2id$v=19$m=65540,t=3,p=4$YOUR_HASH_HERE'
SMTP_USERNAME=your-email@gmail.com
SMTP_PASSWORD=your-app-password

Start the container:

docker compose up -d

Vaultwarden is now running on localhost:8080. But you should never access a password manager over plain HTTP. The next step is critical.

HTTPS With a Reverse Proxy

Bitwarden clients require HTTPS. Browsers block the Web Crypto API on insecure origins. You need TLS, and the easiest way to get it is with Caddy, which handles Let’s Encrypt certificates automatically.

Add Caddy to your docker-compose.yml:

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    environment:
      - DOMAIN=https://vault.yourdomain.com
      - SIGNUPS_ALLOWED=true
      - ADMIN_TOKEN=${ADMIN_TOKEN}
      - LOG_FILE=/data/vaultwarden.log
      - LOG_LEVEL=warn
      - TZ=America/New_York
    volumes:
      - ./vw-data:/data
    networks:
      - proxy

  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
    networks:
      - proxy

networks:
  proxy:
    driver: bridge

Create the Caddyfile:

vault.yourdomain.com {
    reverse_proxy vaultwarden:80
}

That is the entire Caddy configuration. Caddy automatically obtains and renews a Let’s Encrypt certificate for your domain. Make sure your DNS A record points to your server’s public IP and ports 80 and 443 are forwarded to the server.

Option B: Traefik (If You Run Multiple Services)

If you already use Traefik for other services, add labels to the Vaultwarden container instead:

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    environment:
      - DOMAIN=https://vault.yourdomain.com
      - SIGNUPS_ALLOWED=true
      - ADMIN_TOKEN=${ADMIN_TOKEN}
    volumes:
      - ./vw-data:/data
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.vaultwarden.rule=Host(`vault.yourdomain.com`)"
      - "traefik.http.routers.vaultwarden.entrypoints=websecure"
      - "traefik.http.routers.vaultwarden.tls.certresolver=letsencrypt"
      - "traefik.http.services.vaultwarden.loadbalancer.server.port=80"
    networks:
      - traefik

networks:
  traefik:
    external: true

Both options give you automatic HTTPS with certificate renewal. Pick whichever reverse proxy fits your existing stack.

Admin Panel Configuration

Vaultwarden includes a web-based admin panel at /admin. This is where you manage server settings, view registered users, invite new users, and adjust organization policies.

Securing the Admin Token

Never use a plaintext admin token in production. Generate an Argon2 hash:

docker run --rm -it vaultwarden/server /vaultwarden hash --preset owasp

This command prompts you for a password and outputs an Argon2id PHC string. Put that string in your .env file as the ADMIN_TOKEN. When you access /admin, you enter the original password (not the hash).

Important: if you use the hash in a .env file, you must double every $ sign. For example, $argon2id$v=19$ becomes $$argon2id$$v=19$$ in the .env file. Alternatively, put the hash directly in docker-compose.yml wrapped in single quotes to avoid shell interpolation.

Key Admin Settings

Once logged into the admin panel, configure these settings:

  • General Settings > Domain URL: Set to https://vault.yourdomain.com. This ensures email links point to the correct address.
  • General Settings > Allow new signups: Disable after creating your account(s).
  • SMTP Email Settings: Configure so that email verification, password hints, and two-factor recovery work properly.
  • Advanced Settings > Disable icon downloads: Enable if you want to prevent your server from fetching website favicons (minor privacy consideration).

Controlling User Registration

For a personal or family vault, you do not want open registration. There are several approaches:

Disable Signups After Initial Setup

  1. Start with SIGNUPS_ALLOWED=true.
  2. Create your account(s) through the web vault.
  3. Change to SIGNUPS_ALLOWED=false and restart the container.
# Edit docker-compose.yml, then:
docker compose up -d

Use Invitation-Only Registration

Set SIGNUPS_ALLOWED=false and INVITATIONS_ALLOWED=true. Then invite specific users from the admin panel. They receive an email invitation link and can register only through that link.

Domain-Restricted Signups

Allow signups only from specific email domains:

environment:
  - SIGNUPS_ALLOWED=true
  - SIGNUPS_DOMAINS_WHITELIST=yourdomain.com,yourfamily.com

This is useful for small organizations where you want self-service registration but only for people with company email addresses.

Importing From Other Password Managers

Vaultwarden uses the standard Bitwarden web vault for imports, which supports dozens of formats. Log into your web vault at https://vault.yourdomain.com, then navigate to Tools > Import Data.

From LastPass

  1. Log into LastPass in your browser.
  2. Go to Advanced Options > Export > LastPass CSV File.
  3. In Vaultwarden’s web vault, select LastPass (csv) as the import format.
  4. Upload the CSV file.
  5. Delete the exported CSV from your computer immediately — it contains plaintext passwords.

From 1Password

  1. Open 1Password desktop app.
  2. Go to File > Export > All Items.
  3. Choose 1Password Unencrypted Export (.1pux) or CSV format.
  4. In Vaultwarden, select 1Password (1pux) or 1Password (csv) as the format.
  5. Upload the file.

From Chrome/Edge/Brave

  1. Open chrome://password-manager/settings in Chrome.
  2. Click Download File under the Export passwords section.
  3. In Vaultwarden, select Chrome (csv) as the format.
  4. Upload the CSV.

From Firefox

  1. Open about:logins in Firefox.
  2. Click the three-dot menu and select Export Logins.
  3. Import as Firefox (csv) in Vaultwarden.

After importing, verify that your entries look correct. Folders and organizational structure from most managers transfer cleanly. Bitwarden uses “folders” for personal organization and “collections” within organizations for shared vaults.

Mobile App Setup

This is one of Vaultwarden’s best features: the official Bitwarden apps work without modification. No sideloading, no custom builds.

iOS

  1. Install Bitwarden from the App Store.
  2. On the login screen, tap the gear icon (Settings) before logging in.
  3. Under Self-hosted environment, enter your server URL: https://vault.yourdomain.com.
  4. Save and log in with your credentials.

Android

  1. Install Bitwarden from Google Play or F-Droid.
  2. On the login screen, tap the region selector and choose Self-hosted.
  3. Enter your server URL: https://vault.yourdomain.com.
  4. Save and log in.

Browser Extensions

  1. Install the Bitwarden extension for your browser.
  2. Click the extension icon, then the gear icon on the login page.
  3. Set the Server URL to https://vault.yourdomain.com.
  4. Log in.

Auto-fill works identically to the cloud version. TOTP codes generate in the app if you store TOTP secrets in your vault entries. Push sync keeps everything updated within seconds of making changes on any device.

Backup Strategy

Your password vault is arguably the most critical piece of data in your homelab. Losing it locks you out of every service you use. Backups are not optional.

What to Back Up

The Vaultwarden data directory contains everything:

vw-data/
  db.sqlite3          # The database (passwords, users, orgs)
  db.sqlite3-wal      # Write-ahead log (active transactions)
  db.sqlite3-shm      # Shared memory file
  config.json          # Admin panel settings
  rsa_key.pem          # RSA private key
  rsa_key.pub.pem      # RSA public key
  attachments/         # File attachments
  sends/               # Bitwarden Send files
  icon_cache/          # Website favicons (optional, regenerated)

Automated Backup Script

Create a backup script at ~/docker/vaultwarden/backup.sh:

#!/bin/bash
set -euo pipefail

BACKUP_DIR="/path/to/backups/vaultwarden"
VW_DATA="$HOME/docker/vaultwarden/vw-data"
DATE=$(date +%Y-%m-%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/vaultwarden-backup-$DATE.tar.gz"
RETENTION_DAYS=30

mkdir -p "$BACKUP_DIR"

# Use sqlite3 .backup for a consistent database snapshot
sqlite3 "$VW_DATA/db.sqlite3" ".backup '$BACKUP_DIR/db-backup-$DATE.sqlite3'"

# Archive everything including the clean database backup
tar -czf "$BACKUP_FILE" \
  -C "$BACKUP_DIR" "db-backup-$DATE.sqlite3" \
  -C "$VW_DATA" config.json rsa_key.pem rsa_key.pub.pem \
  --ignore-failed-read \
  -C "$VW_DATA" attachments/ sends/ 2>/dev/null || true

# Clean up the temporary database backup
rm "$BACKUP_DIR/db-backup-$DATE.sqlite3"

# Remove backups older than retention period
find "$BACKUP_DIR" -name "vaultwarden-backup-*.tar.gz" -mtime +$RETENTION_DAYS -delete

echo "Backup complete: $BACKUP_FILE"

Make it executable and schedule it with cron:

chmod +x ~/docker/vaultwarden/backup.sh

# Run daily at 3 AM
crontab -e
# Add: 0 3 * * * /home/youruser/docker/vaultwarden/backup.sh

Using the vaultwarden-backup Docker Image

For a purely Docker-based approach, the ttionya/vaultwarden-backup image automates SQLite backups and can push them to remote storage via rclone:

services:
  vaultwarden-backup:
    image: ttionya/vaultwarden-backup:latest
    container_name: vaultwarden-backup
    restart: unless-stopped
    environment:
      - CRON=0 3 * * *
      - ZIP_ENABLE=true
      - ZIP_PASSWORD=${BACKUP_ZIP_PASSWORD}
      - BACKUP_KEEP_DAYS=30
      - RCLONE_REMOTE_NAME=my-remote
      - RCLONE_REMOTE_DIR=/vaultwarden-backups/
    volumes:
      - ./vw-data:/bitwarden/data:ro
      - ./rclone-config:/config/rclone

This approach encrypts backups with a password and pushes them to any storage backend rclone supports — S3, Backblaze B2, Google Drive, SFTP, or dozens of others.

The 3-2-1 Rule

For your password vault specifically, follow the 3-2-1 backup rule strictly:

  • 3 copies: The live database, a local backup, and a remote backup.
  • 2 different media: Local disk and cloud/offsite storage.
  • 1 offsite: At minimum, copy encrypted backups to a different physical location.

Test your restores. A backup you have never tested is not a backup.

Security Hardening

A self-hosted password manager is only as secure as the server it runs on. Apply these hardening measures:

Fail2Ban for Brute Force Protection

Vaultwarden logs failed login attempts. Configure Fail2Ban to block IPs after repeated failures.

Create /etc/fail2ban/filter.d/vaultwarden.conf:

[Definition]
failregex = ^.*?Login attempt from <HOST> for .+\. Username or password is incorrect\.$
            ^.*?Attempt to access admin panel from <HOST> denied\.$
ignoreregex =

Create /etc/fail2ban/jail.d/vaultwarden.local:

[vaultwarden]
enabled = true
port = 80,443
filter = vaultwarden
logpath = /path/to/vw-data/vaultwarden.log
maxretry = 3
bantime = 14400
findtime = 14400

Restart Fail2Ban:

sudo systemctl restart fail2ban

Disable Admin Panel in Production

If you rarely change server settings, disable the admin panel entirely by removing ADMIN_TOKEN from your environment. You can re-enable it temporarily when needed:

# Temporarily enable admin
docker compose exec vaultwarden /bin/sh -c 'export ADMIN_TOKEN=temporary-token'
# Or just add it back to docker-compose.yml, restart, make changes, remove it, restart again

Additional Hardening Steps

  • Keep your server updated: Run apt update && apt upgrade regularly on the host OS.
  • Use a firewall: Only expose ports 80 and 443. Bind Vaultwarden to 127.0.0.1 so it is only reachable through the reverse proxy (as shown in the Compose file above).
  • Enable two-factor authentication: Every Vaultwarden account should have 2FA enabled. Use a hardware key (YubiKey) or TOTP authenticator app.
  • Set a strong master password: Your master password is the single point of defense for your entire vault. Use a passphrase of at least 4-5 random words.
  • Restrict network access: Consider placing Vaultwarden behind a VPN like Tailscale or WireGuard so it is not exposed to the public internet at all.

Rate Limiting at the Reverse Proxy

Add rate limiting in Caddy to slow down automated attacks:

vault.yourdomain.com {
    rate_limit {
        zone dynamic_zone {
            key {remote_host}
            events 10
            window 1m
        }
    }
    reverse_proxy vaultwarden:80
}

Automatic Updates

Keeping Vaultwarden updated is important for security patches and Bitwarden client compatibility. There are two clean approaches:

Watchtower (Automatic)

Watchtower monitors your running containers and pulls new images automatically:

services:
  watchtower:
    image: containrrr/watchtower:latest
    container_name: watchtower
    restart: unless-stopped
    environment:
      - WATCHTOWER_CLEANUP=true
      - WATCHTOWER_SCHEDULE=0 0 4 * * *
      - WATCHTOWER_NOTIFICATIONS=email
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

This checks for updates daily at 4 AM and restarts containers with newer images. The downside is that updates happen without your explicit approval — fine for a personal vault, but consider manual updates if you prefer more control.

Manual Update (Controlled)

cd ~/docker/vaultwarden

# Pull the latest image
docker compose pull

# Recreate the container with the new image
docker compose up -d

# Verify the new version
docker compose logs vaultwarden | head -5

Run this weekly or whenever a new release is announced. Subscribe to releases on the Vaultwarden GitHub repository to get notified.

Monitoring Uptime

A password manager that goes down at the wrong moment — say, when you are trying to log into your bank — is worse than useless. You need to know immediately when your Vaultwarden instance is unreachable.

Set up an external uptime monitor that pings your vault URL at regular intervals. CronPing works well for this: point it at https://vault.yourdomain.com/alive (Vaultwarden’s built-in health endpoint) and configure alerts via email or webhook. If your server goes offline or the container crashes, you get notified within minutes instead of discovering the outage when you desperately need a password.

This is especially important if your Vaultwarden instance is running on a home server where ISP outages, power failures, or accidental reboots can take it offline without warning.

Troubleshooting Common Issues

”This browser requires HTTPS to use the web vault”

You are accessing the vault over HTTP. Set up a reverse proxy with TLS as described above. Even for local testing, you can use Caddy with a self-signed certificate or access via localhost (which browsers treat as a secure context).

Mobile App Cannot Connect

  • Verify the server URL includes https:// and has no trailing slash.
  • Check that your DNS resolves correctly from your phone’s network.
  • If using a VPN, ensure your phone is connected to it.
  • Check Vaultwarden logs: docker compose logs -f vaultwarden.

Admin Panel Returns 404

The admin panel is only available when ADMIN_TOKEN is set. If you removed it for security, add it back and restart the container.

Import Fails or Shows 0 Items

  • Make sure you selected the correct import format.
  • Check that the CSV file is not empty and is properly formatted.
  • For large imports (thousands of entries), try splitting the file into smaller chunks.

High CPU Usage After Upgrade

Occasionally, a new version triggers a database migration or icon cache rebuild. This is temporary. Check logs for migration messages and wait for it to complete.

Here is a complete, production-ready docker-compose.yml incorporating everything in this guide:

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    environment:
      - DOMAIN=https://vault.yourdomain.com
      - SIGNUPS_ALLOWED=false
      - INVITATIONS_ALLOWED=true
      - ADMIN_TOKEN=${ADMIN_TOKEN}
      - SMTP_HOST=${SMTP_HOST}
      - SMTP_FROM=${SMTP_FROM}
      - SMTP_PORT=587
      - SMTP_SECURITY=starttls
      - SMTP_USERNAME=${SMTP_USERNAME}
      - SMTP_PASSWORD=${SMTP_PASSWORD}
      - LOG_FILE=/data/vaultwarden.log
      - LOG_LEVEL=warn
      - IP_HEADER=X-Forwarded-For
      - TZ=America/New_York
    volumes:
      - ./vw-data:/data
    networks:
      - proxy

  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
    networks:
      - proxy

  backup:
    image: ttionya/vaultwarden-backup:latest
    container_name: vaultwarden-backup
    restart: unless-stopped
    environment:
      - CRON=0 3 * * *
      - ZIP_ENABLE=true
      - ZIP_PASSWORD=${BACKUP_ZIP_PASSWORD}
      - BACKUP_KEEP_DAYS=30
    volumes:
      - ./vw-data:/bitwarden/data:ro
      - ./backups:/bitwarden/backup

networks:
  proxy:
    driver: bridge

What to Do Next

Once your vaultwarden setup is running and your passwords are imported:

  1. Enable two-factor authentication on your Vaultwarden account immediately. Use a TOTP app or hardware key.
  2. Install Bitwarden browser extensions on every browser you use. Configure them to point at your self-hosted instance.
  3. Set up mobile apps on your phone and tablet. Verify auto-fill works in both apps and browsers.
  4. Disable the password manager built into your browser (Chrome, Firefox, Safari all have one). You do not want passwords saved in two places.
  5. Run a vault health report from the web vault under Tools > Reports. It flags reused passwords, weak passwords, and exposed passwords from known breaches.
  6. Delete exports from your old password manager. Those unencrypted CSV files are a liability.
  7. Set up your backup and verify you can restore from it by spinning up a test Vaultwarden instance with the backup data.
  8. Configure uptime monitoring so you know the moment your vault goes down.

Self-hosting your password manager is one of the highest-value things you can do in a homelab. The resource cost is negligible, the setup takes an afternoon, and the result is complete sovereignty over the most sensitive data in your digital life. Vaultwarden makes the entire process remarkably painless, and the official Bitwarden clients mean you never sacrifice usability for control.

Your passwords. Your server. Your rules.