Skip to content

Vaultwarden

Bitwarden-Compatible Password Management

Vaultwarden is an unofficial Bitwarden-compatible server written in Rust. It provides a lightweight, resource-efficient alternative to the official Bitwarden server, perfect for self-hosting password management with full client compatibility.

Why Choose Vaultwarden?

  • Bitwarden-compatible - works with all official Bitwarden clients
  • Lightweight - written in Rust with minimal resource usage
  • Secure - end-to-end encryption with zero-knowledge architecture
  • Free - all features included, no subscription fees

Install

Infrastructure as Code

This Vaultwarden instance is deployed using OpenTofu with the official Docker image. The infrastructure configuration manages container provisioning and persistent storage.

Infrastructure Configuration

The OpenTofu configuration provisions:

  • Incus instance running official Vaultwarden Docker image
  • Persistent storage volume for /data directory containing:
    • SQLite database with encrypted vault data
    • User attachments and icons
    • Configuration and keys
OpenTofu Configuration
resource "incus_storage_volume" "vaultwarden_data" {
  name = "vaultwarden_data"
  pool = incus_storage_pool.default.name
}

resource "incus_instance" "vaultwarden" {
  name  = "vaultwarden"
  image = "docker:vaultwarden/server:1.34.3-alpine"

  config = {
    "environment.DOMAIN" = "https://vaultwarden.benoit.jp.net"
    "environment.SIGNUPS_ALLOWED" = "false"
    "environment.SIGNUPS_VERIFY" = "true"
    "environment.SIGNUPS_VERIFY_RESEND_TIME" = "600"
    "environment.IP_HEADER" = "X-Forwarded-For"
    "environment.REQUIRE_DEVICE_EMAIL" = "true"
    "environment.SMTP_HOST" = "mail.benoit.jp.net"
    "environment.SMTP_FROM" = "pwd-no-reply@benoit.jp.net"
    "environment.SMTP_FROM_NAME" = "Vaultwarden"
    "environment.SMTP_USERNAME" = "pwd-no-reply@benoit.jp.net"
    "environment.SMTP_PASSWORD" = "GET_ME_FROM_VAULTWARDEN"  # (1)!
    "environment.SMTP_SECURITY" = "force_tls"
    "environment.SMTP_PORT" = "465"
    "environment.ROCKET_ADDRESS" = "::"
  }

  device {
    name = "data"
    type = "disk"
    properties = {
      path   = "/data"
      source = incus_storage_volume.vaultwarden_data.name
      pool   = incus_storage_pool.default.name
    }
  }
}
  1. Replace with your actual SMTP password for email notifications

Deploy Infrastructure

Apply OpenTofu configuration
tofu apply

Initial Configuration

After provisioning, the Vaultwarden web vault will be available at your configured domain.

First User Registration

Create your admin account immediately after deployment:

  1. Navigate to https://vaultwarden.benoit.jp.net in your browser
  2. Click Create Account to register the first user
  3. After registration, disable signups by setting SIGNUPS_ALLOWED=false (already configured above)
  4. Configure additional users via the admin panel or invitations

Enable Admin Panel

Generate an admin token to access the admin panel:

Enter Incus container
incus shell vaultwarden
Generate admin token
/vaultwarden hash --preset owasp

Add the generated token to your OpenTofu configuration as environment.ADMIN_TOKEN.

TLS Configuration

This instance runs behind a reverse proxy that handles TLS termination. The DOMAIN variable must specify https:// for proper redirect and cookie handling.

Upgrade

Docker Image Upgrade

Upgrading Vaultwarden is straightforward since the /data volume persists independently of the container.

Update OpenTofu configuration

Edit your OpenTofu configuration file to update the image version:

resource "incus_instance" "vaultwarden" {
  name  = "vaultwarden"
  image = "docker:vaultwarden/server:1.35.0-alpine"  # Update version
  # ...
}

Apply infrastructure changes

Recreate container with new image
tofu apply

The container will be recreated with the new image while the data volume remains intact.

Verify upgrade

Check Vaultwarden version
incus exec vaultwarden -- /vaultwarden --version

Navigate to your Vaultwarden web vault and verify functionality.

Upgrade Complete

Your Vaultwarden instance is now running the new version with all your data intact!

Security Best Practices

Critical Security Recommendations

Always enable two-factor authentication for your vault:

  1. Login to web vault
  2. Go to SettingsSecurityTwo-step Login
  3. Enable Authenticator App (TOTP) or YubiKey
  4. Save recovery codes securely offline

Your master password is the only protection for your vault:

  • Use 20+ characters with mixed case, numbers, symbols
  • Never reuse passwords from other services
  • Consider a memorable passphrase (e.g., 5+ random words)
  • Never share your master password
  • Store recovery codes offline in a safe location

Enable email verification for new devices (already configured):

  • Requires email confirmation for new logins
  • Prevents unauthorized access even with password
  • Configure SMTP settings properly for reliability

Always run behind a reverse proxy with:

  • TLS/HTTPS encryption (Let's Encrypt)
  • Rate limiting to prevent brute force
  • Firewall rules to restrict access
  • Fail2ban for automated blocking

Keep Vaultwarden updated for security patches:

  • Monitor release notes
  • Test updates in staging before production
  • Always backup before upgrading

Configuration Options

  • Core Settings


    OpenTofu environment variables
    environment.DOMAIN = "https://vaultwarden.benoit.jp.net"
    environment.ROCKET_ADDRESS = "::"  # Listen on IPv6
    environment.ROCKET_PORT = "80"
    environment.WEB_VAULT_ENABLED = "true"
    
  • User Management


    Registration & invitation settings
    environment.SIGNUPS_ALLOWED = "false"
    environment.SIGNUPS_VERIFY = "true"
    environment.INVITATIONS_ALLOWED = "true"
    environment.SIGNUPS_DOMAINS_WHITELIST = "example.com"
    
  • Email Configuration


    SMTP settings for notifications
    environment.SMTP_HOST = "mail.benoit.jp.net"
    environment.SMTP_PORT = "465"
    environment.SMTP_SECURITY = "force_tls"
    environment.SMTP_USERNAME = "pwd-no-reply@benoit.jp.net"
    environment.SMTP_FROM = "pwd-no-reply@benoit.jp.net"
    
  • Admin Panel


    Enable administrative interface
    environment.ADMIN_TOKEN = "GENERATE_WITH_HASH_COMMAND"
    environment.DISABLE_ADMIN_TOKEN = "false"
    

Related Documentation: