Skip to main content
COSMICBYTEZLABS
NewsSecurityHOWTOsToolsTraining
StudyProjectsNewsletterHire MeAbout
Subscribe

Press Enter to search or Esc to close

News
Security
HOWTOs
Tools
Training
Study
Projects
Newsletter
Hire Me
About
RSS Feed
Reading List
Subscribe

Stay in the Loop

Get the latest security alerts, tutorials, and tech insights delivered to your inbox.

Subscribe NowFree forever. No spam.
COSMICBYTEZLABS

Your trusted source for IT intelligence, cybersecurity insights, and hands-on technical guides.

2604+ Articles
162+ Guides

CONTENT

  • Latest News
  • Security Alerts
  • HOWTOs
  • Checklists
  • Projects
  • Exam Prep

RESOURCES

  • Search
  • Browse Tags
  • Newsletter Archive
  • Reading List
  • RSS Feed

COMPANY

  • About Us
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CosmicBytez Labs. All rights reserved.

System Status: Operational
  1. Home
  2. HOWTOs
  3. Deploying Vaultwarden: A Self-Hosted Password Manager
Deploying Vaultwarden: A Self-Hosted Password Manager
HOWTOIntermediate

Deploying Vaultwarden: A Self-Hosted Password Manager

Stand up a lightweight, Bitwarden-compatible password vault on your own infrastructure — with Docker, TLS via reverse proxy, and an automated backup routine.

Dylan H.

Tutorials

August 31, 2026
6 min read

Prerequisites

  • Docker and Docker Compose installed on a Linux host
  • A domain or subdomain you control, with DNS pointed at the host
  • A reverse proxy (Traefik, Caddy, or nginx) for TLS termination
  • Basic familiarity with environment variables and Docker volumes

Introduction

Password reuse and weak credentials remain the single biggest driver of account compromise for SMBs and homelabs alike. A password manager fixes this, but cloud-hosted vaults put your entire credential store behind a third party's uptime, pricing, and breach history. Vaultwarden (formerly bitwarden_rs) is a lightweight, Rust-based server implementation of the Bitwarden API — it's a drop-in replacement that works with the official Bitwarden browser extensions, mobile apps, and CLI, but runs on hardware you control, using a fraction of the resources of Bitwarden's own self-hosted stack.

In this guide you will:

  • Deploy Vaultwarden with Docker Compose
  • Put it behind a reverse proxy with TLS and security headers
  • Lock down admin access and disable open registration
  • Enable two-factor authentication (TOTP) enforcement
  • Automate encrypted backups of the vault database
  • Verify the deployment and troubleshoot common issues

Prerequisites

Before starting, confirm you have:

  1. A Linux host with Docker Engine and the Compose plugin installed
  2. A DNS record (e.g. vault.example.com) pointed at the host's public or LAN IP
  3. A reverse proxy already terminating TLS for other services (Traefik, Caddy, or nginx + certbot)
  4. At least 512MB of free RAM and 1GB of disk for the vault data volume — Vaultwarden's footprint is small compared to Bitwarden's official Java-based server

Step 1: Generate an Admin Token

Vaultwarden's /admin panel controls users, organizations, and diagnostics. It must be protected with a token — never leave it disabled on an internet-facing instance.

# Generate a strong Argon2 admin token hash
docker run --rm vaultwarden/server:latest /vaultwarden hash

Enter a strong passphrase when prompted. Copy the resulting $argon2id$... hash — you'll paste it into the environment file in Step 2.

Step 2: Create the Docker Compose Stack

Create a project directory and an .env file to keep secrets out of the compose file itself.

mkdir -p /opt/vaultwarden/data
cd /opt/vaultwarden
# .env
DOMAIN=https://vault.example.com
ADMIN_TOKEN='$argon2id$v=19$m=65540,t=3,p=4$...'
SIGNUPS_ALLOWED=false
INVITATIONS_ALLOWED=true
WEBSOCKET_ENABLED=true
# docker-compose.yml
services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    environment:
      DOMAIN: ${DOMAIN}
      ADMIN_TOKEN: ${ADMIN_TOKEN}
      SIGNUPS_ALLOWED: ${SIGNUPS_ALLOWED}
      INVITATIONS_ALLOWED: ${INVITATIONS_ALLOWED}
      WEBSOCKET_ENABLED: ${WEBSOCKET_ENABLED}
      LOG_FILE: /data/vaultwarden.log
    volumes:
      - ./data:/data
    networks:
      - proxy
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.vaultwarden.rule=Host(`vault.example.com`)"
      - "traefik.http.routers.vaultwarden.tls.certresolver=letsencrypt"
      - "traefik.http.services.vaultwarden.loadbalancer.server.port=80"
 
networks:
  proxy:
    external: true

SIGNUPS_ALLOWED=false is critical — it prevents anyone who finds the URL from creating an account. New users are added instead through invitations sent from the admin panel or by a logged-in org admin.

Bring the stack up:

docker compose up -d
docker compose logs -f vaultwarden

Step 3: Harden the Reverse Proxy

If you're using Traefik, add security headers via a middleware so the vault isn't served without HSTS or frame protection:

# traefik dynamic config
http:
  middlewares:
    vaultwarden-headers:
      headers:
        stsSeconds: 31536000
        stsIncludeSubdomains: true
        frameDeny: true
        contentTypeNosniff: true
        browserXssFilter: true

Attach it to the router with an additional label:

labels:
  - "traefik.http.routers.vaultwarden.middlewares=vaultwarden-headers"

For nginx, the equivalent is adding Strict-Transport-Security, X-Frame-Options: DENY, and X-Content-Type-Options: nosniff to the site's server block.

Step 4: Lock Down the Admin Panel

Log in to https://vault.example.com/admin using the plaintext passphrase you hashed in Step 1 (not the hash itself). From here:

  • Under Settings, confirm signups are disabled and set an SMTP relay so invitation and 2FA emails deliver reliably
  • Under Users, review any accounts and revoke ones you don't recognize
  • Consider restricting /admin at the reverse-proxy layer to your LAN or VPN CIDR as a second layer of defense:
# Traefik IP allowlist middleware for /admin
http:
  middlewares:
    admin-allowlist:
      ipAllowList:
        sourceRange:
          - "10.0.0.0/8"
          - "192.168.0.0/16"

Step 5: Enforce Two-Factor Authentication

Vaultwarden supports TOTP, WebAuthn/FIDO2, email codes, and Duo. To require 2FA org-wide, create an organization from a user account, then under Organization Settings → Policies, enable "Require two-step login." Members who haven't configured 2FA will be blocked from vault access until they do.

Individual users enable TOTP from the Bitwarden client under Settings → Security → Two-step Login, scanning the QR code with an authenticator app.

Step 6: Automate Backups

The entire vault lives in /data — primarily db.sqlite3, the attachments/ directory, and rsa_key* files used for JWT signing. Losing the RSA keys invalidates all existing sessions and API keys, so back them up alongside the database.

#!/usr/bin/env bash
# /opt/vaultwarden/backup.sh
set -euo pipefail
 
BACKUP_DIR="/opt/vaultwarden/backups"
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
mkdir -p "$BACKUP_DIR"
 
# SQLite-safe snapshot without stopping the container
docker exec vaultwarden sqlite3 /data/db.sqlite3 ".backup '/data/db-backup.sqlite3'"
 
tar -czf "$BACKUP_DIR/vaultwarden-$TIMESTAMP.tar.gz" \
  -C /opt/vaultwarden/data db-backup.sqlite3 attachments rsa_key.pem rsa_key.pub.pem
 
rm /opt/vaultwarden/data/db-backup.sqlite3
 
# Retain 14 days of backups
find "$BACKUP_DIR" -name "vaultwarden-*.tar.gz" -mtime +14 -delete
chmod +x /opt/vaultwarden/backup.sh

Schedule it with cron and ship the archive off-host (rsync, rclone to object storage, etc.) — a backup that lives on the same disk as the vault doesn't protect against disk failure or ransomware.

0 3 * * * /opt/vaultwarden/backup.sh >> /var/log/vaultwarden-backup.log 2>&1

Verification

Confirm the deployment end-to-end:

# Container is healthy
docker compose ps
 
# HTTPS responds with a valid cert
curl -sI https://vault.example.com | head -n 1
 
# API is reachable
curl -s https://vault.example.com/alive

Install the Bitwarden browser extension or mobile app, choose "Self-hosted" in server settings, enter your domain, and log in with an invited account. Save a test entry, then confirm it syncs by checking the same vault from a second device.

Restore-test the backup at least once:

docker compose stop vaultwarden
tar -xzf backups/vaultwarden-<timestamp>.tar.gz -C /tmp/restore-test
# verify db-backup.sqlite3 opens cleanly
sqlite3 /tmp/restore-test/db-backup.sqlite3 ".tables"
docker compose start vaultwarden

Troubleshooting

"Username or password is incorrect" on first login — Confirm SIGNUPS_ALLOWED was true at the moment you registered the first account, or use an admin-panel invite instead.

WebSocket sync not working (changes don't push to other devices) — Ensure WEBSOCKET_ENABLED=true is set and that your reverse proxy passes through the Upgrade and Connection headers on the /notifications/hub path.

Admin panel returns 404 — The admin interface is disabled entirely if ADMIN_TOKEN is unset or empty. Check docker compose logs vaultwarden for a startup warning confirming the admin route is active.

Emails (invites, 2FA codes) never arrive — Vaultwarden needs explicit SMTP configuration (SMTP_HOST, SMTP_FROM, SMTP_USERNAME, SMTP_PASSWORD); without it, invitation links must be copied manually from the admin panel and shared out-of-band.

Container restarts in a loop after an update — Check for a schema migration failure in the logs; restore the previous backup and pin the image to the last known-good tag before retrying.

Summary

Vaultwarden gives you a fully compatible Bitwarden vault without the resource overhead or vendor dependency of the official self-hosted stack. The critical hardening steps are non-negotiable for anything internet-facing: disable open signups, protect the admin token, terminate TLS properly, enforce 2FA at the organization level, and — above all — back up the SQLite database and RSA keys somewhere that isn't the same disk. A password manager is only as trustworthy as its recovery story.

#vaultwarden#password-management#docker#self-hosted#identity-security#homelab

Related Articles

Self-Hosted Password Manager with Vaultwarden

Deploy a fully self-hosted, Bitwarden-compatible password manager using Vaultwarden on Docker with Caddy reverse proxy, automatic TLS, WebSocket...

10 min read

Self-Hosting a Password Manager: Vaultwarden Setup Guide

Deploy your own password manager with Vaultwarden (Bitwarden-compatible). Includes secure configuration, SSL setup, and backup procedures.

7 min read

Keycloak SSO: Self-Hosted Identity Provider for Your Homelab

Deploy Keycloak with Docker Compose and PostgreSQL to build a centralised single sign-on platform for your homelab services, with OIDC integration for...

11 min read
Back to all HOWTOs