Skip to main content

Self-Hosting Guide: Deploy Bitwarden (Vaultwarden) 2026

·OSSAlt Team
bitwardenvaultwardenpasswordsself-hostingdockerguide
Share:

Bitwarden is the most popular open source password manager. Self-hosting with Vaultwarden (a lightweight, community-maintained Bitwarden-compatible server) gives you all premium features for free — TOTP, file attachments, organizations, and Bitwarden Send — using a fraction of the resources.

Why Vaultwarden?

FeatureOfficial Bitwarden ServerVaultwarden
RAM2+ GB (C#/.NET)50-100 MB (Rust)
Containers10+ services1 container
Premium featuresPaid ($10/year)Free
OrganizationsPaid ($4/user/month)Free
CompatibilityFull APIFull API
LicenseAGPLGPL-3.0

Requirements

  • VPS with 512 MB RAM minimum
  • Docker
  • Domain name (e.g., vault.yourdomain.com)
  • HTTPS required (Bitwarden clients refuse HTTP)
  • 5+ GB disk

Step 1: Deploy with Docker

docker run -d \
  --name vaultwarden \
  --restart unless-stopped \
  -p 8080:80 \
  -v vw-data:/data \
  -e DOMAIN=https://vault.yourdomain.com \
  -e SIGNUPS_ALLOWED=true \
  -e ADMIN_TOKEN=your-long-random-admin-token \
  vaultwarden/server:latest

Generate admin token:

openssl rand -hex 32

Step 2: Reverse Proxy (Caddy) — HTTPS Required

# /etc/caddy/Caddyfile
vault.yourdomain.com {
    reverse_proxy localhost:8080
}
sudo systemctl restart caddy

HTTPS is mandatory. Bitwarden clients will not connect over HTTP.

Step 3: DNS

Add an A record: vault.yourdomain.com → your server IP

Step 4: Create Your Account

  1. Open https://vault.yourdomain.com
  2. Click Create Account
  3. Set a strong master password (this is the only password you need to remember)

Important: After creating your account, disable sign-ups:

docker stop vaultwarden
docker rm vaultwarden
docker run -d \
  --name vaultwarden \
  --restart unless-stopped \
  -p 8080:80 \
  -v vw-data:/data \
  -e DOMAIN=https://vault.yourdomain.com \
  -e SIGNUPS_ALLOWED=false \
  -e ADMIN_TOKEN=your-long-random-admin-token \
  vaultwarden/server:latest

Or use the admin panel to invite specific users.

Step 5: Install Clients

All official Bitwarden clients work with Vaultwarden:

PlatformClientCustom Server URL
BrowserBitwarden extension (Chrome, Firefox, Safari)Settings → Self-hosted → https://vault.yourdomain.com
DesktopBitwarden Desktop (Mac, Windows, Linux)Login → Self-hosted → https://vault.yourdomain.com
iOSBitwarden iOS appLogin → Self-hosted → https://vault.yourdomain.com
AndroidBitwarden Android appLogin → Self-hosted → https://vault.yourdomain.com
CLIbw config server https://vault.yourdomain.comCLI flag

Step 6: Configure SMTP (For Invitations)

docker run -d \
  --name vaultwarden \
  --restart unless-stopped \
  -p 8080:80 \
  -v vw-data:/data \
  -e DOMAIN=https://vault.yourdomain.com \
  -e SIGNUPS_ALLOWED=false \
  -e ADMIN_TOKEN=your-admin-token \
  -e SMTP_HOST=smtp.resend.com \
  -e SMTP_PORT=587 \
  -e SMTP_SECURITY=starttls \
  -e SMTP_USERNAME=resend \
  -e SMTP_PASSWORD=re_your_api_key \
  -e SMTP_FROM=vault@yourdomain.com \
  vaultwarden/server:latest

Step 7: Admin Panel

Access at https://vault.yourdomain.com/admin

Admin capabilities:

  • Invite users (bypasses sign-up restriction)
  • View all users and their status
  • Delete users
  • View organization details
  • Configure server settings
  • Check diagnostics

Step 8: Set Up Organizations (Team Sharing)

  1. Login to web vault
  2. SettingsOrganizationsNew Organization
  3. Invite team members
  4. Create Collections (shared folders):
    • Engineering passwords
    • Infrastructure secrets
    • Marketing accounts
    • Shared company logins

Permissions:

  • Owner → full control
  • Admin → manage collections and members
  • User → access assigned collections
  • Custom → granular permissions per collection

Step 9: Enable 2FA

In your vault → SettingsTwo-step Login:

MethodSetup
Authenticator appScan QR with Google Authenticator, Authy, etc.
EmailReceive code via email
YubiKeyHardware key (premium feature — free in Vaultwarden)
WebAuthn/FIDO2Fingerprint, Face ID, security key

Always set up 2FA. Your master password protects all other passwords.

Step 10: Import Existing Passwords

  1. Export from your current password manager:

    • 1Password → .1pux or CSV
    • LastPass → CSV
    • Chrome → CSV (chrome://settings/passwords → Export)
    • KeePass → .kdbx or CSV
  2. In Bitwarden web vault → ToolsImport data

  3. Select format and upload

  4. Verify imported entries

Production Hardening

Docker Compose (recommended):

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    ports:
      - "8080:80"
    volumes:
      - vw-data:/data
    environment:
      - DOMAIN=https://vault.yourdomain.com
      - SIGNUPS_ALLOWED=false
      - ADMIN_TOKEN=your-admin-token
      - SMTP_HOST=smtp.resend.com
      - SMTP_PORT=587
      - SMTP_SECURITY=starttls
      - SMTP_USERNAME=resend
      - SMTP_PASSWORD=re_your_api_key
      - SMTP_FROM=vault@yourdomain.com
      - LOG_LEVEL=warn
      - WEBSOCKET_ENABLED=true

volumes:
  vw-data:

Backups (CRITICAL — this is your password vault):

# Daily backup of the data directory
docker run --rm -v vw-data:/data -v /backups:/backup alpine \
  tar czf /backup/vaultwarden-$(date +%Y%m%d).tar.gz /data

# Copy backup off-server (S3, another VPS, or local)
rclone copy /backups/vaultwarden-$(date +%Y%m%d).tar.gz remote:backups/

Set up multiple backup locations. If you lose this data, you lose all passwords.

Updates:

docker pull vaultwarden/server:latest
docker stop vaultwarden
docker rm vaultwarden
# Re-run docker run command (data persists in volume)

Security:

  • Strong admin token (64+ characters)
  • Disable sign-ups after creating accounts
  • Enable 2FA for all users
  • Regular backups to off-site locations
  • Monitor for unauthorized access in admin panel
  • Keep Vaultwarden updated

Resource Usage

UsersRAMCPUDisk
1-1050 MB1 core100 MB
10-50100 MB1 core500 MB
50-200256 MB1 core1 GB

Vaultwarden is incredibly lightweight — it can easily share a VPS with other services.

VPS Recommendations

ProviderSpecPrice
Hetzner2 vCPU, 2 GB RAM€4.50/month
DigitalOcean1 vCPU, 1 GB RAM$6/month
Linode1 vCPU, 1 GB RAM$5/month

vs Bitwarden Teams ($4/user/month): A 20-person team saves $960/year with self-hosted Vaultwarden.

Why Self-Host Bitwarden (Vaultwarden)

Bitwarden's commercial plans are actually reasonably priced compared to 1Password and LastPass. The individual Premium plan is $10/year — genuinely affordable. But team and enterprise costs add up: Bitwarden Teams is $4/user/month, meaning a 20-person company pays $960/year. A 50-person company pays $2,400/year. 1Password Teams runs $7.99/user/month — $4,794/year for 50 people. LastPass Teams is $4/user/month. Over three years with modest team growth, password manager costs for medium-sized companies routinely reach $10,000–20,000.

Self-hosted Vaultwarden provides every feature of Bitwarden's Premium and Teams plans — TOTP generation, organizations, collections, Bitwarden Send, emergency access, file attachments, and WebAuthn/FIDO2 — at zero license cost. The savings for a 20-person team are $960/year. For a 100-person company, the savings exceed $4,800/year against Bitwarden Teams or $9,500/year against 1Password. The operational cost (one developer spending a few hours per year on maintenance) is minimal by comparison.

Full data control for credentials: A password manager holds the keys to your entire digital infrastructure. Self-hosting means those credentials are encrypted and stored only on servers you control. No vendor breach can expose your vault data. No vendor business changes affect your access. This is the most compelling case for self-hosting any tool — credentials are uniquely sensitive.

All premium features for free: The comparison table above captures the key difference between Vaultwarden and the official Bitwarden server: Vaultwarden's maintainers have implemented all premium API endpoints, so features that cost money on the official server (TOTP, file attachments, organizations, YubiKey 2FA) are free. A solo developer who needs TOTP support but doesn't want to pay $10/year can self-host instead.

When NOT to self-host Bitwarden: Password vault availability is critical — if your vault server goes down, your team can't access credentials. A misconfigured or poorly maintained server is a security liability. If you or your team lacks the technical capacity to ensure uptime and keep the server updated, the risk of self-hosting outweighs the cost savings. Bitwarden's $10/year individual plan is genuinely good value for individuals who want managed hosting. For teams, do the math honestly: at small scale (under 10 people), the operational overhead may not justify the savings.

Prerequisites (Expanded)

512 MB RAM minimum: Vaultwarden is written in Rust and has an exceptionally small memory footprint — 50 MB at idle for a single-user instance. The 512 MB minimum is generous; in practice, Vaultwarden shares a server comfortably with other services. The key hardware requirement is not RAM but reliability — your password vault needs high uptime.

HTTPS required: This is non-negotiable. Every Bitwarden client (browser extension, desktop app, mobile app) refuses to connect to a server over plain HTTP. Caddy makes HTTPS automatic and free via Let's Encrypt. The configuration in this guide handles certificate provisioning automatically — you don't need to manually manage certificates.

Domain name: The domain you use for Vaultwarden becomes permanently baked into your vault's configuration. Changing domains later requires updating the server URL in every client. Choose a domain you control long-term — vault.yourdomain.com is a good pattern.

5+ GB disk: Vaultwarden stores vault data in an SQLite database and a small data directory. For most users, the database stays well under 50 MB even with thousands of vault items. The 5 GB minimum provides headroom for file attachments (if enabled) and long-term growth.

For server selection, Vaultwarden's low resource requirements mean you can run it on the cheapest tier at any major provider. See the VPS comparison for self-hosters for a comparison of entry-tier options — Hetzner's CX11 (€3.79/month) and DigitalOcean's $6/month Droplet both work well for Vaultwarden.

Production Security Hardening

Your password vault is the highest-value target in your infrastructure. Compromise here means compromise of everything. Apply every hardening step — no exceptions.

Firewall with UFW: Vaultwarden runs on port 8080 internally. Only expose ports 80, 443, and 22.

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

Fail2ban: Protect against brute-force login attempts on the vault.

sudo apt install fail2ban

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

[Definition]
failregex = ^.*Username or password is incorrect\. Try again\. IP: <HOST>\. Username:.*$
ignoreregex =

Add to /etc/fail2ban/jail.local:

[vaultwarden]
enabled = true
port = http,https
filter = vaultwarden
logpath = /path/to/vaultwarden.log
maxretry = 3
bantime = 14400
findtime = 14400

Never commit secrets to version control: Your ADMIN_TOKEN, SMTP credentials, and any other environment variables must stay out of Git. Use a .env file excluded from version control, or pass environment variables directly to docker run.

Use a 64-character admin token: The example uses openssl rand -hex 32 (generates 64 hex characters). Shorter tokens are less resistant to brute-force attacks on the admin endpoint. Use 64 characters minimum.

Disable sign-ups immediately after setup: With SIGNUPS_ALLOWED=true, anyone who finds your vault URL can create an account. Disable this the moment your accounts are created. You can still invite users via the admin panel.

Disable SSH password authentication:

sudo sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo systemctl restart sshd

Enable automatic security updates:

sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades

Off-site backups — this is critical: The backup command in the Production Hardening section creates a local backup. Local backups alone are insufficient — disk failure or server deletion destroys them too. Set up automated off-site backups using automated server backups with restic. Store encrypted backup copies in at least two locations (e.g., Backblaze B2 + a second VPS). Test your restore procedure before you need it.

For the complete hardening checklist applicable to any self-hosted service, see the self-hosting security checklist.

Troubleshooting Common Issues

Bitwarden clients say "invalid server URL" or refuse to connect

Check that the URL in the client exactly matches DOMAIN in your Vaultwarden configuration — including the https:// prefix and no trailing slash. If you recently changed your domain, Vaultwarden may still have the old domain cached. Restart the container after any domain change. Also verify that your SSL certificate is valid:

curl -I https://vault.yourdomain.com

Admin panel is accessible from the internet

The admin panel at /admin should be restricted. Your admin token is the only thing protecting it. Consider adding IP-based restrictions in Caddy:

vault.yourdomain.com {
    handle /admin* {
        @not_my_ip not remote_ip YOUR_IP
        respond @not_my_ip 403
        reverse_proxy localhost:8080
    }
    handle {
        reverse_proxy localhost:8080
    }
}

2FA tokens are invalid ("Invalid TOTP code")

TOTP codes are time-based and require synchronized clocks. If your server's system clock is drifted, tokens generated by your phone will be rejected. Check server time:

timedatectl

If the time is wrong, synchronize NTP:

sudo timedatectl set-ntp true
sudo systemctl restart systemd-timesyncd

Organization invitations aren't being received

SMTP must be configured for email invitations. Without SMTP, Vaultwarden cannot send invitation emails. Check the admin panel's SMTP configuration under Settings and send a test email. Also check that the invited email address is valid and check spam folders — invitation emails from self-hosted servers sometimes land there initially.

Container data not persisting after restart

This indicates the Docker volume isn't mounted correctly. The -v vw-data:/data flag in the docker run command creates a named Docker volume. Verify with:

docker volume ls | grep vw-data
docker volume inspect vw-data

If you're using Docker Compose, ensure the volumes: section is correctly defined and that you're using docker compose down (not docker compose down -v) — the -v flag deletes volumes.

Browser extension stops working after Vaultwarden update

Vaultwarden occasionally changes its API in ways that require client updates. If the extension suddenly stops syncing after a Vaultwarden update, check that you're running the latest version of the Bitwarden browser extension and that your Vaultwarden version is compatible with the client. The Vaultwarden GitHub releases page lists known client compatibility requirements.


Compare password managers on OSSAlt — features, security, and pricing side by side.

See open source alternatives to Bitwarden on OSSAlt.

The SaaS-to-Self-Hosted Migration Guide (Free PDF)

Step-by-step: infrastructure setup, data migration, backups, and security for 15+ common SaaS replacements. Used by 300+ developers.

Join 300+ self-hosters. Unsubscribe in one click.