🎯 New! Master certifications with Performance-Based Questions (PBQ) — realistic hands-on practice for CompTIA & Cisco exams!

Vaultwarden Complete Self-Hosting Guide 2026: Free Bitwarden Alternative Setup

Published on January 10, 2026


Introduction

Vaultwarden (formerly known as Bitwarden_RS) is an unofficial, open-source, community-driven server implementation of the Bitwarden password manager API. Written in Rust, Vaultwarden is designed to be lightweight, efficient, and easy to self-host—making it an ideal choice for individuals, families, and small organizations who want complete control over their password data.

This comprehensive guide covers every aspect of Vaultwarden deployment, from basic Docker installation to advanced configurations including reverse proxy setup, two-factor authentication, email configuration, and enterprise-grade backup strategies.

What is Vaultwarden?

Vaultwarden is a re-implementation of the Bitwarden server API. This means:

  • It works with all official Bitwarden client applications (browser extensions, desktop apps, mobile apps)
  • Your passwords are encrypted client-side before reaching the server
  • It includes premium features for free that would require a subscription with official Bitwarden

Vaultwarden vs Official Bitwarden: Key Differences

AspectVaultwardenOfficial Bitwarden Self-Hosted
TechnologyRust (single binary).NET + SQL Server
RAM Usage~30-50 MB2-4 GB minimum
Docker Containers1 container6-8 containers
Setup ComplexitySimpleComplex
Premium Features✅ Free (TOTP, 2FA, Organizations)Requires subscription
Official Support❌ Community-driven✅ Official support
Third-Party Audits❌ No formal audits✅ Regular security audits
DatabaseSQLite (default), MySQL, PostgreSQLSQL Server
Target AudienceIndividuals, families, small orgsEnterprise, large organizations

⚠️ Important Note: While Vaultwarden is secure (passwords are encrypted client-side), it has not undergone formal third-party security audits like the official Bitwarden server. Evaluate your security requirements before choosing.

Who Is This Guide For?

  • Beginners setting up their first self-hosted password manager
  • Privacy-conscious users wanting full control over their passwords
  • Home lab enthusiasts looking for a lightweight password solution
  • Small teams needing shared password management without subscription costs
  • Raspberry Pi users seeking resource-efficient applications

Part 1: System Requirements

Hardware Requirements

Vaultwarden is extremely lightweight and can run on minimal hardware:

ComponentMinimumRecommendedNotes
RAM128 MB256 MB+Vaultwarden uses ~30-50 MB
CPUAnyAnyRust is highly efficient
Storage100 MB1 GB+For database and attachments
Architecturex86_64, ARM64, ARMv7AnySupports Raspberry Pi

Supported Platforms

PlatformSupport LevelNotes
Linux (Ubuntu/Debian)✅ ExcellentRecommended for production
Linux (Other distros)✅ GoodDocker works on most distros
Windows (WSL2)⚠️ GoodVia Docker Desktop
macOS⚠️ GoodVia Docker Desktop
Synology/QNAP NAS✅ GoodContainer Manager support
Raspberry Pi✅ ExcellentPerfect for Pi 3/4/5
Unraid✅ GoodCommunity templates available

Network Requirements

PortProtocolPurposeRequired
80TCPHTTP (redirects, Let’s Encrypt)✅ For SSL
443TCPHTTPS (main access)✅ Recommended
3012TCPWebSocket notificationsOptional
Custom (e.g., 8080)TCPLocal-only accessOptional

Critical Security Requirement: HTTPS

🔒 HTTPS is Required: Bitwarden clients require HTTPS for production use. Running Vaultwarden without HTTPS is only acceptable for:

  • Local network access only (e.g., 192.168.x.x)
  • Development and testing purposes

This guide covers setting up HTTPS via reverse proxy.


Part 2: Prerequisites

Before installing Vaultwarden, prepare your system with these essential steps. This ensures you have the necessary tools and security basics in place.

Step 1: Update Your System

Updating ensures you have the latest security patches and software versions.

For *nix (Linux - e.g., Ubuntu/Debian):

# Update package lists
sudo apt update

# Upgrade all installed packages
sudo apt upgrade -y

Command breakdown:

  • sudo: Runs the command with administrator (root) privileges - you’ll enter your password
  • apt: Package manager for Debian-based systems like Ubuntu
  • update: Refreshes the list of available packages from repositories
  • upgrade -y: Installs newer versions; -y automatically confirms prompts

For other Linux distributions:

# Fedora/RHEL/CentOS
sudo dnf update -y

# Arch Linux
sudo pacman -Syu

# openSUSE
sudo zypper update

For macOS:

# Update system software
softwareupdate -i -a

Command breakdown:

  • softwareupdate: Apple’s built-in system update tool
  • -i: Install updates
  • -a: All available updates

For Windows (PowerShell as Administrator):

# Update all apps via Windows Package Manager
winget upgrade --all

# Or use Windows Update via Settings
# Settings > Update & Security > Windows Update > Check for updates

Step 2: Create a Dedicated User (Security Best Practice)

Running services as root or your main user is a security risk. Create a dedicated user for Vaultwarden.

For *nix (Linux):

# Create a new user named 'vaultuser'
sudo adduser vaultuser

What this does: Creates a new system user. You’ll be prompted to set a password and optional user details (press Enter to skip).

# Add the user to the sudo group (for admin tasks)
sudo usermod -aG sudo vaultuser

Command breakdown:

  • usermod: Modifies a user account
  • -aG: Appends to group without removing from other groups
  • sudo: The administrators group
# Switch to the new user
su - vaultuser

Command breakdown:

  • su: Switch user
  • -: Loads the new user’s full environment (home directory, shell settings)

For macOS:

  1. Go to System SettingsUsers & Groups
  2. Click the lock icon and authenticate
  3. Click + to add a new user
  4. Create a Standard user named “vaultuser”
  5. In Terminal, grant admin access:
sudo dscl . -append /Groups/admin GroupMembership vaultuser

For Windows:

# Create a new local user (PowerShell as Administrator)
$Password = Read-Host -AsSecureString "Enter password"
New-LocalUser "vaultuser" -Password $Password -Description "Vaultwarden Service Account"

# Add to Administrators group
Add-LocalGroupMember -Group "Administrators" -Member "vaultuser"

Step 3: Install Git (For Repository Cloning)

Git is a version control tool used to download source code. While not strictly required for Docker installation, it’s useful for future updates and native builds.

For *nix (Linux):

sudo apt install git -y

For Fedora:

sudo dnf install git -y

For macOS:

# Install Xcode Command Line Tools (includes Git)
xcode-select --install

# Or via Homebrew (if installed)
brew install git

For Windows:

  1. Download from git-scm.com
  2. Run the installer with default options
  3. Open Git Bash (installed with Git) for Unix-like commands

Verify Installation:

git --version
# Expected: git version 2.x.x

Step 4: Install a Text Editor

You’ll need a text editor for editing configuration files.

For *nix (Linux):

# Nano - beginner-friendly editor
sudo apt install nano -y

# Or Vim - more powerful, steeper learning curve
sudo apt install vim -y

Nano basics:

  • Open file: nano filename
  • Save: Ctrl+O, then Enter
  • Exit: Ctrl+X

For macOS:

Nano is pre-installed. Alternatively:

# Install via Homebrew
brew install nano

For Windows:

Download Notepad++ or use built-in Notepad.


Step 5: Configure Firewall

Firewalls block unauthorized access to your server. Configure them to allow only necessary ports.

For *nix (Ubuntu/Debian with UFW):

# Install UFW if not present
sudo apt install ufw -y

# Allow SSH (for remote access - skip if local only)
sudo ufw allow OpenSSH

# Allow HTTP (for Let's Encrypt certificate verification)
sudo ufw allow 80/tcp

# Allow HTTPS (for secure web access)
sudo ufw allow 443/tcp

# Enable the firewall
sudo ufw enable

What this does:

  • allow OpenSSH: Permits SSH connections (port 22)
  • allow 80/tcp: Permits HTTP connections
  • allow 443/tcp: Permits HTTPS connections
  • enable: Activates the firewall (answer y when prompted)
# Check firewall status
sudo ufw status

For Fedora/RHEL/CentOS (firewalld):

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

For macOS:

  1. Open System SettingsNetworkFirewall
  2. Turn on the firewall
  3. Click Options to configure specific app permissions

For Windows:

  1. Open Windows SecurityFirewall & network protection
  2. Click Allow an app through firewall
  3. Add entries for ports 80 and 443 when needed

Step 6: Domain Name Setup

For external access with HTTPS, you need a domain name pointing to your server.

Option A: Use a Free Dynamic DNS Service (DuckDNS)

DuckDNS provides free subdomains that update automatically.

  1. Go to duckdns.org and sign in
  2. Create a subdomain (e.g., yourvault.duckdns.org)
  3. Note your token from the DuckDNS dashboard
  4. Update it to point to your public IP (visible at whatismyip.com)

Automatic IP Updates (for dynamic IPs):

Create a cron job to update your IP automatically:

# Edit crontab
crontab -e

# Add this line (updates every 5 minutes)
*/5 * * * * curl -s "https://www.duckdns.org/update?domains=yourvault&token=YOUR_TOKEN_HERE&ip=" >/dev/null 2>&1

Command breakdown:

  • */5 * * * *: Run every 5 minutes
  • curl -s: Silently calls the DuckDNS update URL
  • >/dev/null 2>&1: Suppresses output

Option B: Use a Purchased Domain

  1. Purchase a domain from a registrar (Namecheap, Cloudflare, GoDaddy, etc.)
  2. In your registrar’s DNS settings, create an A record:
    • Name: vault (or @ for root domain)
    • Type: A
    • Value: Your server’s public IP address
    • TTL: 300 (or Auto)

💡 Security Tip: Avoid using “bitwarden” or “password” in your domain name - obscurity adds a small layer of protection.


Step 7: Port Forwarding (For Home Networks)

If hosting at home behind a router, forward ports 80 and 443 to your server:

  1. Find your server’s local IP: ip a (Linux) or ipconfig (Windows)
  2. Log into your router (usually 192.168.1.1 or 192.168.0.1)
  3. Find Port Forwarding settings (varies by router)
  4. Add rules:
    • External Port 80 → Internal IP, Port 80
    • External Port 443 → Internal IP, Port 443
  5. Save and apply

⚠️ Security Warning: Exposing ports to the internet increases attack surface. Ensure Vaultwarden and your server are properly secured.


Part 3: Docker Installation

Docker is the recommended method for running Vaultwarden as it provides isolation, easy updates, and consistent behavior across platforms.

This is the preferred setup for Vaultwarden in production environments.

Step 1: Update System Packages

# Update package index
sudo apt update

# Upgrade existing packages
sudo apt upgrade -y

What this does: Ensures your system has the latest security patches and package information before installing new software.

Step 2: Remove Conflicting Docker Versions

# Remove old Docker packages that might conflict
for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do
  sudo apt-get remove -y $pkg 2>/dev/null
done

What this does: Removes outdated Docker packages from default repositories that might conflict with the official Docker installation.

Step 3: Install Docker Prerequisites

# Install required packages
sudo apt-get install -y 
  ca-certificates 
  curl 
  gnupg 
  lsb-release

Package breakdown:

  • ca-certificates: Enables HTTPS communication
  • curl: Tool for downloading files from URLs
  • gnupg: GNU Privacy Guard for verifying package signatures
  • lsb-release: Identifies the Linux distribution

Step 4: Add Docker’s Official GPG Key

# Create directory for keyrings
sudo install -m 0755 -d /etc/apt/keyrings

# Download and install Docker's GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | 
  sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# Ensure key is readable
sudo chmod a+r /etc/apt/keyrings/docker.gpg

What this does: Downloads Docker’s official signing key, which verifies that Docker packages are authentic and haven’t been tampered with.

Step 5: Add Docker Repository

# Add Docker repository to apt sources
echo 
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg]   https://download.docker.com/linux/ubuntu   $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | 
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

What this does: Adds Docker’s official package repository, ensuring you get the latest Docker version with all features and security updates.

💡 Note for Debian: Replace ubuntu with debian in the URL above if using Debian.

Step 6: Install Docker Engine

# Update package index with new repository
sudo apt-get update

# Install Docker Engine and plugins
sudo apt-get install -y 
  docker-ce 
  docker-ce-cli 
  containerd.io 
  docker-buildx-plugin 
  docker-compose-plugin

Package breakdown:

  • docker-ce: Docker Community Edition (the main engine)
  • docker-ce-cli: Command-line interface for Docker
  • containerd.io: Container runtime
  • docker-buildx-plugin: Enhanced image building capabilities
  • docker-compose-plugin: Docker Compose V2 (uses docker compose instead of docker-compose)
# Add current user to docker group
sudo usermod -aG docker $USER

# Apply group changes immediately (or log out and back in)
newgrp docker

What this does: Allows running Docker commands without sudo. You must log out and log back in for changes to take effect permanently.

⚠️ Security Note: Adding a user to the docker group grants them root-equivalent access on the system. Only add trusted users.

Step 8: Enable Docker to Start on Boot

# Enable Docker service
sudo systemctl enable docker

# Start Docker service
sudo systemctl start docker

What this does: Ensures Docker starts automatically when your server boots up.

Step 9: Verify Installation

# Check Docker version
docker --version

# Expected output: Docker version 25.x.x, build xxxxxxx

# Check Docker Compose version
docker compose version

# Expected output: Docker Compose version v2.x.x

# Test Docker with hello-world
docker run hello-world

If you see the “Hello from Docker!” message, your installation is successful.


Option B: Windows (Docker Desktop + WSL2)

Docker Desktop provides an easy way to run Docker on Windows using WSL2 (Windows Subsystem for Linux 2).

Prerequisites

  • Windows 10 version 21H2 or higher, or Windows 11
  • 64-bit processor with Second Level Address Translation (SLAT)
  • 4 GB RAM minimum (8 GB recommended)
  • Virtualization enabled in BIOS

Step 1: Enable WSL2

Open PowerShell as Administrator and run:

# Install WSL with the default Ubuntu distribution
wsl --install

# This will:
# - Enable Windows Subsystem for Linux feature
# - Enable Virtual Machine Platform feature
# - Install the Linux kernel update package
# - Set WSL 2 as the default version
# - Install Ubuntu distribution

Restart your computer when prompted.

Step 2: Verify WSL2 Installation

After restart, open PowerShell:

# Check WSL status
wsl --status

# List installed distributions
wsl --list --verbose

Ensure the VERSION column shows “2” for your distribution.

Step 3: Download and Install Docker Desktop

  1. Visit Docker Desktop for Windows
  2. Download the installer (Docker Desktop Installer.exe)
  3. Run the installer with these options:
    • Use WSL 2 instead of Hyper-V (Critical!)
    • Add shortcut to desktop (Optional)
  4. Click OK to proceed with installation
  5. Restart your computer when prompted

Step 4: Configure Docker Desktop

  1. Launch Docker Desktop from Start Menu
  2. Accept the Docker Subscription Service Agreement
  3. When Docker Desktop opens, go to Settings (gear icon)
  4. Navigate to ResourcesWSL Integration
  5. Toggle ON for your default WSL distro (Ubuntu)
  6. Click Apply & Restart

Step 5: Verify Docker Installation

Open PowerShell or Windows Terminal:

# Check Docker version
docker --version

# Check Docker Compose version
docker compose version

# Test Docker
docker run hello-world

You should see the “Hello from Docker!” message.

💡 Tip: For best performance, store your Vaultwarden data inside WSL2 (e.g., /home/yourusername/vaultwarden) rather than on Windows drives.


Option C: macOS (Docker Desktop)

Prerequisites

  • macOS 12 (Monterey) or newer
  • Apple Silicon (M1/M2/M3/M4) or Intel processor
  • 4 GB RAM minimum (8 GB recommended)

Step 1: Download Docker Desktop

  1. Visit Docker Desktop for Mac
  2. Download the appropriate version:
    • Apple Silicon (M1/M2/M3/M4): Download “Apple Chip” version
    • Intel Macs: Download “Intel Chip” version

Step 2: Install Docker Desktop

  1. Open the downloaded .dmg file
  2. Drag the Docker icon to the Applications folder
  3. Open Docker from the Applications folder
  4. Accept the Docker Subscription Service Agreement

Step 3: Configure Resources (Optional)

  1. Click the Docker icon in the menu bar
  2. Go to SettingsResources
  3. Adjust memory allocation if needed (default is usually sufficient)
  4. For Apple Silicon, enable Use Virtualization framework (faster)

Step 4: Verify Installation

Open Terminal:

# Check Docker version
docker --version

# Check Docker Compose version
docker compose version

# Test Docker
docker run hello-world

Option D: Alternative Method Using Homebrew (macOS)

# Install Docker via Homebrew
brew install --cask docker

# Launch Docker (first time setup)
open /Applications/Docker.app

# Verify installation after Docker starts
docker --version

Part 4: Vaultwarden Installation

This section covers two methods for installing Vaultwarden with Docker: the simple CLI method and the recommended Docker Compose method.

Method 1: Simple Docker CLI (Quick Start)

For a quick installation without a configuration file, use the Docker CLI directly.

For All Platforms:

# Create data directory for persistence
mkdir -p ~/vaultwarden/data

Basic Run Command:

# Pull the latest Vaultwarden image
docker pull vaultwarden/server:latest

# Run Vaultwarden container
docker run -d 
  --name vaultwarden 
  -e DOMAIN="https://vault.yourdomain.com" 
  -e SIGNUPS_ALLOWED=true 
  -e WEBSOCKET_ENABLED=true 
  -v ~/vaultwarden/data:/data 
  -p 8080:80 
  -p 3012:3012 
  --restart unless-stopped 
  vaultwarden/server:latest

Command breakdown:

  • -d: Run in detached mode (background)
  • --name vaultwarden: Name the container for easy reference
  • -e DOMAIN=...: Set environment variable for your server URL
  • -e SIGNUPS_ALLOWED=true: Allow user registrations
  • -e WEBSOCKET_ENABLED=true: Enable real-time sync
  • -v ~/vaultwarden/data:/data: Mount persistent data volume
  • -p 8080:80: Map container port 80 to host port 8080
  • -p 3012:3012: Map WebSocket port
  • --restart unless-stopped: Auto-restart unless manually stopped
  • vaultwarden/server:latest: The official Vaultwarden image

Managing the Container:

# Check if container is running
docker ps

# View logs
docker logs vaultwarden

# Follow logs in real-time
docker logs -f vaultwarden

# Stop the container
docker stop vaultwarden

# Start the container
docker start vaultwarden

# Remove the container (data is preserved in volume)
docker rm vaultwarden

# Update to latest version
docker pull vaultwarden/server:latest
docker stop vaultwarden
docker rm vaultwarden
# Re-run the docker run command above

Windows (PowerShell):

# Create data directory
New-Item -ItemType Directory -Force -Path "$HOMEaultwardendata"

# Run Vaultwarden
docker run -d `
  --name vaultwarden `
  -e DOMAIN="https://vault.yourdomain.com" `
  -e SIGNUPS_ALLOWED=true `
  -v "${HOME}aultwardendata:/data" `
  -p 8080:80 `
  --restart unless-stopped `
  vaultwarden/server:latest

💡 When to use CLI vs Compose: Use CLI for testing or simple setups. Use Docker Compose (below) for production, as it’s easier to manage configuration changes.


Docker Compose is the recommended method for running Vaultwarden as it provides easy configuration management and container orchestration.

Step 1: Create Project Directory

Linux/macOS:

# Create directory for Vaultwarden
mkdir -p ~/vaultwarden
cd ~/vaultwarden

# Create data directory
mkdir -p data

Windows (PowerShell):

# Create directory for Vaultwarden
New-Item -ItemType Directory -Force -Path "$HOMEaultwardendata"
Set-Location "$HOMEaultwarden"

Step 2: Create Docker Compose File

Create a file named docker-compose.yml:

Linux/macOS:

nano docker-compose.yml

Windows (PowerShell):

notepad docker-compose.yml

Add the following content:

# Vaultwarden Docker Compose Configuration
# https://github.com/dani-garcia/vaultwarden

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    
    # Environment variables for configuration
    environment:
      # ==========================================
      # DOMAIN CONFIGURATION (Required for HTTPS)
      # ==========================================
      # Your Vaultwarden domain with https://
      - DOMAIN=https://vault.yourdomain.com
      
      # ==========================================
      # SIGNUP SETTINGS
      # ==========================================
      # Allow new user registrations (set to false after initial setup)
      - SIGNUPS_ALLOWED=true
      
      # Only allow signups from specific email domain(s)
      # - SIGNUPS_DOMAINS_WHITELIST=yourdomain.com,otherdomain.org
      
      # Require email verification for new signups
      - SIGNUPS_VERIFY=true
      
      # ==========================================
      # ADMIN PANEL (Highly Recommended)
      # ==========================================
      # Generate a secure token with: openssl rand -base64 48
      # Or use: docker exec -it vaultwarden /vaultwarden hash
      - ADMIN_TOKEN=YOUR_SECURE_ADMIN_TOKEN_HERE
      
      # ==========================================
      # WEBSOCKET NOTIFICATIONS
      # ==========================================
      # Enable for real-time sync across devices
      - WEBSOCKET_ENABLED=true
      
      # ==========================================
      # LOGGING
      # ==========================================
      - LOG_LEVEL=warn
      # Options: trace, debug, info, warn, error, off
      
      # ==========================================
      # TWO-FACTOR AUTHENTICATION
      # ==========================================
      # Set organization name for Authenticator apps
      - AUTHENTICATOR_DISABLE_TIME_DRIFT=false
      
      # ==========================================
      # INVITATIONS
      # ==========================================
      - INVITATIONS_ALLOWED=true
      
    # Volume mapping for persistent data
    volumes:
      # Map host data directory to container
      # Linux/macOS: ./data:/data
      # Windows: Adjust path as needed
      - ./data:/data
    
    # Port mapping
    ports:
      # Main web interface (change left side to use different port)
      - "8080:80"
      # WebSocket port for notifications
      - "3012:3012"

Important: Replace YOUR_SECURE_ADMIN_TOKEN_HERE with a secure token (see next section).

Step 3: Generate a Secure Admin Token

The ADMIN_TOKEN protects your admin panel. Generate a secure token:

# Generate a random 48-character token
openssl rand -base64 48

Copy the output and replace YOUR_SECURE_ADMIN_TOKEN_HERE in your docker-compose.yml.

Option 2: Using Argon2 Hash (Most Secure)

For enhanced security, use an Argon2 hash instead of a plain token:

# Start Vaultwarden temporarily
docker run --rm -it vaultwarden/server /vaultwarden hash

# Enter your desired admin password when prompted
# Copy the entire hash output (starts with $argon2id$...)

The hash will look like:

$argon2id$v=19$m=65540,t=3,p=4$bXl...

Use this entire string as your ADMIN_TOKEN value.

Step 4: Understanding Environment Variables

Here’s a comprehensive list of all important Vaultwarden environment variables:

Core Settings

VariableDescriptionDefault
DOMAINYour Vaultwarden URL (e.g., https://vault.example.com)None
SIGNUPS_ALLOWEDAllow new user registrationstrue
INVITATIONS_ALLOWEDAllow user invitationstrue
ADMIN_TOKENPassword/hash for admin panelNone (admin disabled)
WEBSOCKET_ENABLEDEnable WebSocket notificationsfalse
LOG_LEVELLogging verbosityInfo

User Registration Controls

VariableDescriptionDefault
SIGNUPS_VERIFYRequire email verificationfalse
SIGNUPS_DOMAINS_WHITELISTRestrict signups to email domainsNone
DISABLE_ICON_DOWNLOADDisable downloading website iconsfalse

Security Settings

VariableDescriptionDefault
PASSWORD_HINTS_ALLOWEDAllow password hintstrue
SHOW_PASSWORD_HINTShow hints on login pagefalse
DISABLE_2FA_REMEMBERDisable “remember 2FA” optionfalse

SMTP/Email Configuration (For Verification)

VariableDescriptionExample
SMTP_HOSTSMTP server addresssmtp.gmail.com
SMTP_PORTSMTP port587
SMTP_SECURITYConnection securitystarttls
SMTP_USERNAMESMTP usernameyour@email.com
SMTP_PASSWORDSMTP password or app passwordyour-app-password
SMTP_FROMFrom email addressvault@yourdomain.com
SMTP_FROM_NAMEFrom display nameVaultwarden

Step 5: Start Vaultwarden

# Navigate to your Vaultwarden directory
cd ~/vaultwarden

# Pull the image and start the container
docker compose up -d

# -d flag runs in detached (background) mode

What this command does:

  1. Pulls the latest Vaultwarden image from Docker Hub
  2. Creates the container with your configuration
  3. Starts the container in the background

Step 6: Verify Vaultwarden is Running

# Check container status
docker compose ps

# Expected output:
# NAME          STATUS          PORTS
# vaultwarden   Up (healthy)    0.0.0.0:8080->80/tcp, 0.0.0.0:3012->3012/tcp

# View container logs
docker compose logs -f

# Press Ctrl+C to exit log view

Step 7: Access Vaultwarden

  1. Open your web browser
  2. Navigate to http://YOUR_SERVER_IP:8080
    • Or http://localhost:8080 if running locally
  3. You should see the Vaultwarden web interface

⚠️ Warning: Until you set up HTTPS, only access Vaultwarden from your local network!


Part 5: Reverse Proxy Setup (HTTPS)

For secure external access, you need to set up a reverse proxy with SSL/TLS certificates. This section covers two popular options: Caddy and Nginx Proxy Manager.

Understanding Reverse Proxies

A reverse proxy:

  1. Receives HTTPS requests from the internet
  2. Terminates SSL/TLS encryption
  3. Forwards requests to Vaultwarden (via HTTP internally)
  4. Returns encrypted responses to clients
                                            ┌────────────────────┐
Internet ──► Reverse Proxy (HTTPS:443) ──► │   Vaultwarden      │
              │ SSL Termination           │   (HTTP:8080)      │
              │ Let's Encrypt Certs       └────────────────────┘
              └──────────────────────────────────────────────────

Prerequisites for All Methods

Before setting up a reverse proxy:

  1. Domain Name: Own a domain (e.g., yourdomain.com) or subdomain (e.g., vault.yourdomain.com)
  2. DNS Record: Create an A record pointing your domain to your server’s public IP
  3. Port Forwarding: Forward ports 80 and 443 from your router to your server
  4. Firewall: Allow incoming connections on ports 80 and 443

Option A: Caddy Reverse Proxy (Simplest)

Caddy is an excellent choice for Vaultwarden because:

  • Automatic HTTPS: Obtains and renews Let’s Encrypt certificates automatically
  • Simple configuration: Minimal setup required
  • Built-in HTTP/2 and HTTP/3 support

Step 1: Update Docker Compose

Create a new docker-compose.yml with Caddy included:

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    environment:
      - DOMAIN=https://vault.yourdomain.com
      - SIGNUPS_ALLOWED=true
      - ADMIN_TOKEN=YOUR_SECURE_ADMIN_TOKEN
      - WEBSOCKET_ENABLED=true
    volumes:
      - ./vw-data:/data
    # Note: No ports exposed - Caddy will handle external access
    networks:
      - vaultwarden-network
    
  caddy:
    image: caddy:latest
    container_name: caddy
    restart: unless-stopped
    ports:
      - "80:80"       # Required for Let's Encrypt HTTP challenge
      - "443:443"     # HTTPS
      - "443:443/udp" # HTTP/3 (QUIC)
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - ./caddy-data:/data
      - ./caddy-config:/config
    networks:
      - vaultwarden-network

networks:
  vaultwarden-network:
    driver: bridge

Step 2: Create Caddyfile

Create a file named Caddyfile in the same directory:

nano Caddyfile

Add the following content:

# Vaultwarden Caddy Configuration
# Replace vault.yourdomain.com with your actual domain

vault.yourdomain.com {
    # Enable logging
    log {
        level INFO
        output file /data/access.log {
            roll_size 10mb
            roll_keep 10
        }
    }
    
    # Security headers
    header {
        # Enable strict HTTPS
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
        # Prevent XSS attacks
        X-XSS-Protection "1; mode=block"
        # Prevent MIME type sniffing
        X-Content-Type-Options "nosniff"
        # Control iframe embedding
        X-Frame-Options "SAMEORIGIN"
        # Referrer policy
        Referrer-Policy "strict-origin-when-cross-origin"
        # Remove server header
        -Server
    }
    
    # Proxy all requests to Vaultwarden
    reverse_proxy vaultwarden:80 {
        # WebSocket support
        header_up X-Real-IP {remote_host}
    }
    
    # Handle WebSocket notifications (optional, for real-time sync)
    reverse_proxy /notifications/hub vaultwarden:3012
}

What each section does:

  • vault.yourdomain.com: Your domain - Caddy automatically gets SSL certificates
  • log: Access logging with rotation
  • header: Security headers to protect against common attacks
  • reverse_proxy: Forwards requests to the Vaultwarden container

Step 3: Start the Stack

# Create required directories
mkdir -p vw-data caddy-data caddy-config

# Start all containers
docker compose up -d

# Check logs for SSL certificate acquisition
docker compose logs caddy -f

Caddy will automatically:

  1. Detect the domain in your Caddyfile
  2. Request an SSL certificate from Let’s Encrypt
  3. Configure HTTPS redirects
  4. Renew certificates automatically

Step 4: Verify HTTPS

Open https://vault.yourdomain.com in your browser. You should see:

  • A valid SSL certificate (padlock icon)
  • The Vaultwarden login page

Option B: Nginx Proxy Manager (GUI-Based)

Nginx Proxy Manager (NPM) provides a user-friendly web interface for managing reverse proxies.

Step 1: Create Docker Compose with NPM

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    environment:
      - DOMAIN=https://vault.yourdomain.com
      - SIGNUPS_ALLOWED=true
      - ADMIN_TOKEN=YOUR_SECURE_ADMIN_TOKEN
      - WEBSOCKET_ENABLED=true
    volumes:
      - ./vw-data:/data
    networks:
      - proxy-network
    
  nginx-proxy-manager:
    image: jc21/nginx-proxy-manager:latest
    container_name: nginx-proxy-manager
    restart: unless-stopped
    ports:
      - "80:80"     # HTTP
      - "443:443"   # HTTPS
      - "81:81"     # NPM Admin Panel
    volumes:
      - ./npm-data:/data
      - ./npm-letsencrypt:/etc/letsencrypt
    networks:
      - proxy-network

networks:
  proxy-network:
    driver: bridge

Step 2: Start the Containers

mkdir -p vw-data npm-data npm-letsencrypt
docker compose up -d

Step 3: Access NPM Admin Panel

  1. Open http://YOUR_SERVER_IP:81
  2. Log in with default credentials:
    • Email: admin@example.com
    • Password: changeme
  3. Immediately change these credentials when prompted

Step 4: Configure Proxy Host for Vaultwarden

  1. In NPM, go to HostsProxy Hosts

  2. Click Add Proxy Host

  3. Fill in the Details tab:

    • Domain Names: vault.yourdomain.com
    • Scheme: http
    • Forward Hostname/IP: vaultwarden
    • Forward Port: 80
    • Block Common Exploits: ✅ Enable
    • Websockets Support: ✅ Enable
  4. Go to the SSL tab:

    • SSL Certificate: Request a new SSL Certificate
    • Force SSL: ✅ Enable
    • HTTP/2 Support: ✅ Enable
    • HSTS Enabled: ✅ Enable
    • Click Save
  5. NPM will automatically obtain a Let’s Encrypt certificate

Step 5: Verify the Setup

Navigate to https://vault.yourdomain.com and verify:

  • Valid SSL certificate
  • Vaultwarden web interface loads correctly

Option C: Existing Nginx Server

If you already have Nginx installed, add this configuration:

Create Nginx Site Configuration

sudo nano /etc/nginx/sites-available/vaultwarden
# Redirect HTTP to HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name vault.yourdomain.com;
    
    # Let's Encrypt verification
    location /.well-known/acme-challenge/ {
        root /var/www/html;
    }
    
    # Redirect all other requests to HTTPS
    location / {
        return 301 https://$host$request_uri;
    }
}

# HTTPS Server
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name vault.yourdomain.com;

    # SSL Configuration
    ssl_certificate /etc/letsencrypt/live/vault.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/vault.yourdomain.com/privkey.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
    
    # Modern SSL configuration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    # Allow large file uploads (for attachments)
    client_max_body_size 525M;

    # Security headers
    add_header Strict-Transport-Security "max-age=63072000" always;
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options SAMEORIGIN;
    add_header X-XSS-Protection "1; mode=block";

    # Main location - proxy to Vaultwarden
    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # WebSocket support for notifications
    location /notifications/hub {
        proxy_pass http://127.0.0.1:3012;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
    
    location /notifications/hub/negotiate {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Enable the Site and Get SSL Certificate

# Enable the site
sudo ln -s /etc/nginx/sites-available/vaultwarden /etc/nginx/sites-enabled/

# Test configuration
sudo nginx -t

# If test passes, reload Nginx
sudo systemctl reload nginx

# Obtain SSL certificate
sudo certbot --nginx -d vault.yourdomain.com

Part 6: Initial Configuration

Step 1: Create Your Admin Account

  1. Navigate to https://vault.yourdomain.com (your Vaultwarden URL)
  2. Click Create Account
  3. Enter:
    • Email: Your email address
    • Name: Your display name
    • Master Password: A strong, unique password
    • Master Password Hint: (Optional, not recommended)
  4. Click Submit

🔒 Master Password Tips:

  • Use at least 16 characters
  • Mix uppercase, lowercase, numbers, and symbols
  • Consider using a passphrase (e.g., “correct-horse-battery-staple”)
  • Never reuse passwords - this should be unique
  • Store your master password securely (consider writing it down and keeping it in a safe)

Step 2: Access the Admin Panel

The admin panel provides server-wide configuration options:

  1. Navigate to https://vault.yourdomain.com/admin
  2. Enter your ADMIN_TOKEN (from your docker-compose.yml)
  3. You’ll see the admin dashboard with various settings

Key Admin Panel Sections

SectionPurpose
General SettingsDomain, icons, attachments
UsersManage registered users
OrganizationsView/manage organizations
DiagnosticsSystem information and health
SMTP SettingsConfigure email delivery

Step 3: Configure SMTP (For Email Verification)

Email is required for:

  • Account verification
  • Password reset
  • Organization invitations
  • Two-step login email codes

Option A: Configure via Admin Panel

  1. Go to Admin Panel → SMTP Email Settings
  2. Enter your SMTP details:
    • Host: Your SMTP server (e.g., smtp.gmail.com)
    • Port: Usually 587 (STARTTLS) or 465 (SSL)
    • From Address: noreply@yourdomain.com
    • From Name: Vaultwarden
    • Username: Your email/SMTP username
    • Password: Your email password or app-specific password
    • Security: starttls or force_tls
  3. Click Save and then Send Test Email

Option B: Configure via Environment Variables

Add to your docker-compose.yml:

environment:
  # ... other variables ...
  - SMTP_HOST=smtp.gmail.com
  - SMTP_PORT=587
  - SMTP_SECURITY=starttls
  - SMTP_USERNAME=your.email@gmail.com
  - SMTP_PASSWORD=your-app-password
  - SMTP_FROM=vault@yourdomain.com
  - SMTP_FROM_NAME=Vaultwarden

💡 Gmail Users: You must use an App Password, not your regular Gmail password.

After creating accounts for yourself and any family/team members:

Method 1: Via Admin Panel

  1. Go to Admin Panel → General Settings
  2. Set Allow New Signups to No
  3. Click Save

Method 2: Via Environment Variable Update docker-compose.yml:

environment:
  - SIGNUPS_ALLOWED=false

Then restart:

docker compose down
docker compose up -d

Step 5: Invite New Users (When Signups Disabled)

With signups disabled, invite users via email:

  1. Go to Admin Panel → Users
  2. Click Invite User
  3. Enter the email address
  4. The user receives an invitation email to create their account

Part 7: Two-Factor Authentication (2FA)

Vaultwarden supports multiple 2FA methods to protect your vault.

Available 2FA Methods

MethodDescriptionSecurity Level
Authenticator App (TOTP)Time-based codes from apps like Authy/Google Authenticator⭐⭐⭐ Good
WebAuthn/FIDO2Hardware security keys (YubiKey, etc.)⭐⭐⭐⭐⭐ Excellent
Email CodesOne-time codes sent via email⭐⭐ Basic
Duo SecurityDuo Mobile push notifications⭐⭐⭐⭐ Very Good

Setting Up Authenticator App (TOTP)

  1. Log in to your Vaultwarden web vault
  2. Go to SettingsSecurityTwo-step Login
  3. Click Manage next to Authenticator App
  4. Enter your master password when prompted
  5. Scan the QR code with your authenticator app:
    • Recommended: Authy, Aegis, Google Authenticator, Microsoft Authenticator
  6. Enter the 6-digit code from your app to verify
  7. Save your recovery code somewhere secure (not in your vault!)

Setting Up WebAuthn/FIDO2 (Hardware Keys)

Hardware security keys like YubiKey provide the strongest protection:

  1. Go to SettingsSecurityTwo-step Login
  2. Click Manage next to FIDO2 WebAuthn
  3. Enter your master password
  4. Give your key a name (e.g., “Primary YubiKey”)
  5. Insert your security key when prompted
  6. Touch the key to confirm
  7. Save your recovery code

💡 Recommendation: Register at least 2 security keys - one for regular use and one as backup.

Recovery Codes

⚠️ Critical: Always save your recovery code when enabling 2FA!

The recovery code is your emergency access method if you lose your 2FA device. Store it:

  • In a physical safe
  • With a trusted family member
  • On an encrypted USB drive in a secure location
  • NOT in your password vault (you can’t access it without 2FA!)

Part 8: Client Applications Setup

Browser Extensions

Installing the Extension

  1. Install the Bitwarden extension for your browser:

  2. Click the Bitwarden icon → Click the Gear icon (Settings)

  3. Go to Settings → scroll to Self-Hosted Environment

  4. Enter your server URL:

    • Server URL: https://vault.yourdomain.com
  5. Click Save

  6. Log in with your Vaultwarden credentials

Desktop Applications

  1. Download Bitwarden Desktop:

  2. Open the app → Click Gear icon (before logging in)

  3. Enter your Self-Hosted Server URL: https://vault.yourdomain.com

  4. Click Save and log in

Mobile Applications

iOS

  1. Download Bitwarden from App Store
  2. Open the app
  3. Tap Log in
  4. Tap Self-hosted (or gear icon before logging in)
  5. Enter Server URL: https://vault.yourdomain.com
  6. Tap Save and log in
  7. Enable Auto-fill:
    • Settings → Passwords → AutoFill Passwords → Bitwarden

Android

  1. Download Bitwarden from Play Store or F-Droid
  2. Open the app
  3. Tap Log in
  4. Tap the Gear icon
  5. Enter Server URL: https://vault.yourdomain.com
  6. Tap Save and log in
  7. Enable Auto-fill:
    • Settings → Passwords & accounts → Autofill service → Bitwarden

Part 9: Backup and Restore

Regular backups are essential for your password vault. Vaultwarden uses a SQLite database that can be easily backed up.

What to Back Up

File/FolderDescriptionPriority
db.sqlite3Main database with all vault dataCritical
rsa_key.pemRSA private keyCritical
rsa_key.pub.pemRSA public keyImportant
attachments/Attachment filesImportant
config.jsonConfigurationLow (can rebuild)

Method 1: Manual Backup

# Stop the container temporarily
docker compose stop vaultwarden

Step 2: Create Backup

# Navigate to your Vaultwarden directory
cd ~/vaultwarden

# Create backup directory with timestamp
backup_dir="backup_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$backup_dir"

# Copy data directory
cp -r data/* "$backup_dir/"

# Create compressed archive
tar -czvf "vaultwarden_backup_$(date +%Y%m%d_%H%M%S).tar.gz" "$backup_dir"

# Clean up temporary directory
rm -rf "$backup_dir"

Step 3: Restart Vaultwarden

docker compose start vaultwarden

Method 2: Using Built-in Backup Command

Vaultwarden includes a built-in backup command:

# Create database backup without stopping the container
docker exec vaultwarden /vaultwarden backup

# This creates a timestamped backup file in the data directory
# e.g., db_20250110_120000.sqlite3

Method 3: Automated Daily Backups

Create an automated backup script:

nano ~/vaultwarden/backup.sh
#!/bin/bash
# Vaultwarden Automated Backup Script

# Configuration
VAULTWARDEN_DIR="$HOME/vaultwarden"
BACKUP_DIR="$HOME/vaultwarden-backups"
RETENTION_DAYS=30

# Create backup directory
mkdir -p "$BACKUP_DIR"

# Create timestamp
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

# Create backup using built-in command
docker exec vaultwarden /vaultwarden backup

# Compress entire data directory
tar -czvf "$BACKUP_DIR/vaultwarden_$TIMESTAMP.tar.gz" 
  -C "$VAULTWARDEN_DIR" data

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

# Log backup completion
echo "[$(date)] Backup completed: vaultwarden_$TIMESTAMP.tar.gz" >> "$BACKUP_DIR/backup.log"

Make it executable and schedule with cron:

# Make script executable
chmod +x ~/vaultwarden/backup.sh

# Open crontab
crontab -e

# Add daily backup at 2:00 AM
0 2 * * * /home/yourusername/vaultwarden/backup.sh

Restoring from Backup

Step 1: Stop Vaultwarden

cd ~/vaultwarden
docker compose down

Step 2: Extract Backup

# Remove existing data (make sure you have a backup!)
rm -rf data/*

# Extract backup
tar -xzvf vaultwarden_backup_YYYYMMDD_HHMMSS.tar.gz

# Move extracted files to data directory
mv backup_YYYYMMDD_HHMMSS/* data/

If restoring only the database file:

# Remove WAL file if exists (prevents corruption)
rm -f data/db.sqlite3-wal

# Copy backup database
cp db_backup.sqlite3 data/db.sqlite3

Step 3: Restart Vaultwarden

docker compose up -d

# Check logs for any issues
docker compose logs -f

Backup Best Practices

  1. 3-2-1 Rule: 3 copies, 2 different media types, 1 offsite
  2. Encrypt backups before storing in cloud (use gpg or age)
  3. Test restores periodically
  4. Document your backup procedure
  5. Store encryption keys separately from backups

Method 4: Incremental Backups with rsync/robocopy

For efficient incremental backups that only copy changed files:

For Linux/macOS (rsync):

# Basic incremental backup
rsync -av ~/vaultwarden/data/ /backup/path/vaultwarden/

# Command breakdown:
# -a: Archive mode (preserves permissions, timestamps, etc.)
# -v: Verbose output

# With deletion of removed files (mirror backup)
rsync -av --delete ~/vaultwarden/data/ /backup/path/vaultwarden/

# To a remote server via SSH
rsync -avz -e ssh ~/vaultwarden/data/ user@backup-server:/backup/vaultwarden/
# -z: Compress during transfer for faster remote backups

Automate with cron:

# Edit crontab
crontab -e

# Add daily rsync backup at 2:30 AM
30 2 * * * rsync -av --delete ~/vaultwarden/data/ /backup/vaultwarden/ >> /var/log/vaultwarden-backup.log 2>&1

For Windows (Robocopy):

# Basic incremental backup
robocopy C:aultwardendata D:ackupaultwarden /MIR /R:3 /W:10

# Command breakdown:
# /MIR: Mirror mode (deletes files in destination not in source)
# /R:3: Retry 3 times on failure
# /W:10: Wait 10 seconds between retries

# With logging
robocopy C:aultwardendata D:ackupaultwarden /MIR /R:3 /W:10 /LOG:C:ackupaultwarden-backup.log

Automate with Task Scheduler:

  1. Open Task Scheduler
  2. Create Basic Task → Name: “Vaultwarden Backup”
  3. Trigger: Daily at 2:00 AM
  4. Action: Start a program → robocopy
  5. Arguments: C:\vaultwarden\data D:\backup\vaultwarden /MIR /R:3 /W:10

Part 10: Updating Vaultwarden

Keeping Vaultwarden updated ensures you have the latest security patches and features.

Standard Update Procedure

# Navigate to your Vaultwarden directory
cd ~/vaultwarden

# Pull the latest image
docker compose pull

# Restart with new image
docker compose up -d

# Verify the update
docker compose logs -f

Update to Specific Version

If you want to pin to a specific version:

# In docker-compose.yml, change:
image: vaultwarden/server:latest

# To a specific version:
image: vaultwarden/server:1.30.5

Then run:

docker compose up -d

Automatic Updates with Watchtower

Watchtower can automatically update your containers:

# Add to docker-compose.yml
services:
  watchtower:
    image: containrrr/watchtower
    container_name: watchtower
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      # Update at 4 AM daily
      - WATCHTOWER_SCHEDULE=0 0 4 * * *
      # Only update labeled containers (optional)
      # - WATCHTOWER_LABEL_ENABLE=true

⚠️ Caution: While convenient, automatic updates can cause issues if an update introduces breaking changes. Consider using monitored updates or setting up notifications.


Part 11: Troubleshooting

Common Issues and Solutions

Issue: Cannot Access Vaultwarden at All

Symptoms: Browser says “Unable to connect” or times out

Solutions:

# Check if container is running
docker compose ps

# If not running, check logs
docker compose logs vaultwarden

# Verify port is listening
sudo netstat -tlnp | grep 8080  # Linux
# or
lsof -i :8080  # macOS

Issue: SSL Certificate Errors

Symptoms: Browser shows “Not Secure” or certificate warnings

Solutions:

  1. Verify DNS is correctly pointing to your server:
    dig vault.yourdomain.com
  2. Check Caddy/Nginx logs for certificate issues:
    docker compose logs caddy
  3. Ensure ports 80 and 443 are open in your firewall

Issue: WebSocket Connection Failed

Symptoms: Changes don’t sync in real-time across devices

Solutions:

  1. Verify WEBSOCKET_ENABLED=true in environment
  2. Check if port 3012 is accessible
  3. Ensure reverse proxy is configured for WebSocket upgrades

Issue: Email Not Sending

Symptoms: Can’t verify email or send invitations

Solutions:

  1. Test SMTP settings in Admin Panel
  2. Check SMTP credentials and allow less secure apps (for Gmail)
  3. Verify SIGNUPS_VERIFY=true if using email verification

Issue: Admin Panel Not Accessible

Symptoms: /admin shows “Admin Panel not enabled”

Solutions:

  1. Verify ADMIN_TOKEN is set in docker-compose.yml
  2. Restart the container after adding token
  3. Check for syntax errors in ADMIN_TOKEN value

Viewing Logs

# View all logs
docker compose logs

# View Vaultwarden logs only
docker compose logs vaultwarden

# Follow logs in real-time
docker compose logs -f

# View last 100 lines
docker compose logs --tail 100

Debug Mode

For troubleshooting, enable debug logging:

environment:
  - LOG_LEVEL=debug
  # or for very detailed output:
  - LOG_LEVEL=trace

Restart and check logs for detailed information.


Part 12: Security Best Practices

Server-Level Security

  1. Keep everything updated

    • Host operating system
    • Docker
    • Vaultwarden container
  2. Use a firewall

    # Allow only necessary ports (Linux UFW)
    sudo ufw allow 22/tcp    # SSH
    sudo ufw allow 80/tcp    # HTTP (for SSL)
    sudo ufw allow 443/tcp   # HTTPS
    sudo ufw enable
  3. Disable root SSH login

    # In /etc/ssh/sshd_config:
    PermitRootLogin no
  4. Enable Fail2Ban for brute-force protection

    Fail2Ban monitors logs and bans IPs with too many failed login attempts.

    Installation and Configuration:

    # Install Fail2Ban
    sudo apt install fail2ban -y
    
    # Create Vaultwarden jail configuration
    sudo nano /etc/fail2ban/jail.d/vaultwarden.local

    Add this configuration:

    [vaultwarden]
    enabled = true
    port = 80,443
    filter = vaultwarden
    action = iptables-allports[name=vaultwarden]
    logpath = /path/to/vaultwarden/data/vaultwarden.log
    maxretry = 5
    bantime = 3600
    findtime = 600

    Create the filter:

    sudo nano /etc/fail2ban/filter.d/vaultwarden.conf

    Add:

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

    Enable Vaultwarden logging (add to docker-compose.yml):

    environment:
      - LOG_FILE=/data/vaultwarden.log
      - LOG_LEVEL=warn

    Start Fail2Ban:

    sudo systemctl enable fail2ban
    sudo systemctl restart fail2ban
    
    # Check status
    sudo fail2ban-client status vaultwarden
  5. Consider VPN Access for extra security

    Instead of exposing Vaultwarden directly to the internet, access it only through a VPN:

    • WireGuard: Modern, fast VPN (recommended)
    • OpenVPN: Established, widely supported
    • Tailscale: Easy mesh VPN with zero configuration

    Benefits:

    • No public exposure of your Vaultwarden server
    • Encrypted tunnel for all traffic
    • Access from anywhere securely

Vaultwarden-Specific Security

  1. Use a strong ADMIN_TOKEN (hash, not plaintext)

  2. Disable signups after setup

    - SIGNUPS_ALLOWED=false
  3. Enable email verification

    - SIGNUPS_VERIFY=true
  4. Enforce 2FA for all users (through policy)

  5. Regular backups stored securely offsite

  6. Use HTTPS only (never expose HTTP)

  7. Hide password hints

    - SHOW_PASSWORD_HINT=false
  8. Disable icon downloads (prevents potential security issues)

    - DISABLE_ICON_DOWNLOAD=true

Personal Security

  1. Use a strong, unique master password
  2. Enable 2FA on your Vaultwarden account
  3. Save recovery codes in a secure physical location
  4. Regularly audit vault entries and active sessions
  5. Log out sessions on devices you no longer use
  6. Use hardware security keys (YubiKey, etc.) for maximum protection

Part 13: Advanced Configuration

Custom Icons

You can mount a custom icons directory:

volumes:
  - ./data:/data
  - ./icons:/icons
environment:
  - ICON_CACHE_FOLDER=/icons

Database Options

Vaultwarden supports multiple databases:

SQLite (Default)

# No additional configuration needed
# Uses data/db.sqlite3 automatically

MySQL/MariaDB

environment:
  - DATABASE_URL=mysql://user:password@mysql:3306/vaultwarden

PostgreSQL

environment:
  - DATABASE_URL=postgresql://user:password@postgres:5432/vaultwarden

Memory Limits

Limit container resources:

services:
  vaultwarden:
    deploy:
      resources:
        limits:
          memory: 256M

Quick Reference

Essential Commands

CommandDescription
docker compose up -dStart containers
docker compose downStop containers
docker compose logs -fView live logs
docker compose pullUpdate images
docker compose restartRestart containers
docker exec -it vaultwarden /bin/shShell into container

Important URLs

URLPurpose
https://vault.yourdomain.comMain web vault
https://vault.yourdomain.com/adminAdmin panel
https://vault.yourdomain.com/apiAPI endpoint (for clients)

Environment Variable Quick Reference

VariableExampleDescription
DOMAINhttps://vault.example.comServer URL
SIGNUPS_ALLOWEDtrue/falseAllow registrations
ADMIN_TOKENsecure-hash-or-tokenAdmin panel password
WEBSOCKET_ENABLEDtrueReal-time sync
SMTP_HOSTsmtp.gmail.comEmail server

Conclusion

You now have a fully functional, secure Vaultwarden installation! This self-hosted password manager gives you:

  • ✅ Complete control over your password data
  • ✅ HTTPS encrypted access
  • ✅ Two-factor authentication
  • ✅ Multi-device synchronization
  • ✅ Premium Bitwarden features at no cost
  • ✅ Automated backups

Next Steps

  1. Import existing passwords from your current password manager
  2. Install browser extensions on all devices
  3. Set up family/team members with their own accounts
  4. Review and organize your vault with folders and collections
  5. Set up organizations for shared passwords

Additional Resources


Last updated: January 2026

Comments

Sign in to join the discussion!

Your comments help others in the community.