Technology Encyclopedia Home >How to Self-Host Vaultwarden (Bitwarden) Password Manager on a VPS

How to Self-Host Vaultwarden (Bitwarden) Password Manager on a VPS

I use a password manager for everything — every account, every service. My passwords are the most sensitive data I generate. I'd been on a hosted password manager and the service worked fine, but I spent more time than I'd like thinking about what happens if the company has a breach, gets acquired, or changes its pricing.

Vaultwarden is the self-hosted answer. It's a Rust reimplementation of the Bitwarden server that's compatible with all official Bitwarden clients — the same browser extensions, desktop apps, and mobile apps work without any modification. You run the server, your clients connect to it, your passwords never leave your infrastructure.

HTTPS is absolutely required — password managers should never run on plain HTTP. This guide includes the Nginx and SSL setup as a mandatory part of the installation.

Self-hosting your password manager means your vault is under your control, not on someone else's servers.

I run Vaultwarden on Tencent Cloud Lighthouse. It uses less than 100 MB RAM — it runs comfortably on the entry-level plan alongside other services. The key reason to use a reliable cloud server for a password manager specifically: uptime — if Vaultwarden is down, you can't access new passwords. Lighthouse's stable infrastructure and the ability to configure automatic snapshots means your vault data is both available and backed up. HTTPS is required for Vaultwarden, and Lighthouse's OrcaTerm makes it easy to set up Certbot without a local SSH client.


Table of Contents

  1. Why Self-Host Your Password Manager?
  2. Prerequisites
  3. Part 1 — Server Setup
  4. Part 2 — Deploy Vaultwarden with Docker
  5. Part 3 — Configure Nginx Reverse Proxy
  6. Part 4 — Enable HTTPS (Required)
  7. Part 5 — Initial Admin Setup
  8. Part 6 — Connect Bitwarden Clients
  9. Part 7 — Configure Admin Panel
  10. Part 8 — Backups (Critical)
  11. The Gotcha: HTTPS Is Not Optional
  12. Security Best Practices

  • Key Takeaways
  • Use the appropriate Lighthouse application image to skip manual installation steps where available
  • Lighthouse snapshots provide one-click full-server backup before major changes
  • OrcaTerm browser terminal lets you manage the server from any device
  • CBS cloud disk expansion handles growing storage needs without server migration
  • Console-level firewall + UFW = two independent protection layers

Why Self-Host Your Password Manager? {#why}

  • Zero trust in third parties — your vault data never touches Bitwarden's or any other company's servers
  • Free premium features — Vaultwarden unlocks features that require Bitwarden Premium, including TOTP authenticator, file attachments, and emergency access
  • No subscription fees — just the server cost
  • Full data control — export, migrate, and delete your data on your own terms

Prerequisites {#prerequisites}

Requirement Notes
Cloud server Tencent Cloud Lighthouse — select Docker CE application image for pre-installed Docker
Docker + Compose Pre-installed with Docker CE image; or install manually
Domain name + HTTPS Required — Bitwarden clients reject HTTP connections
Strong server security Password manager = high-value target

Part 1 — Server Setup {#part-1}

ssh ubuntu@YOUR_SERVER_IP
sudo apt update && sudo apt upgrade -y

curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER
newgrp docker

sudo apt install -y nginx
sudo ufw allow ssh
sudo ufw allow 'Nginx Full'
sudo ufw enable

Part 2 — Deploy Vaultwarden with Docker {#part-2}

mkdir -p ~/apps/vaultwarden && cd ~/apps/vaultwarden

Create .env:

nano .env
# Admin token — set a strong random value
# Access admin panel at: https://vault.yourdomain.com/admin
ADMIN_TOKEN=generate_a_strong_random_token_here

# Domain (required for WebSocket and push notifications)
DOMAIN=https://vault.yourdomain.com

# Enable user registration (set to false after creating your account)
SIGNUPS_ALLOWED=true

# Email settings (for password reset, 2FA, etc.)
SMTP_HOST=smtp.mailgun.org
SMTP_FROM=vaultwarden@yourdomain.com
SMTP_FROM_NAME=Vaultwarden
SMTP_PORT=587
SMTP_SSL=true
SMTP_USERNAME=postmaster@mg.yourdomain.com
SMTP_PASSWORD=your_smtp_password
chmod 600 .env

Create docker-compose.yml:

version: '3.8'

services:
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    ports:
      - "3012:3012"   # WebSocket notifications
      - "8080:80"     # Web vault
    volumes:
      - vaultwarden_data:/data
    env_file:
      - .env

volumes:
  vaultwarden_data:
docker compose up -d
docker compose logs -f vaultwarden
# Wait for: Rocket has launched from http://0.0.0.0:80

Part 3 — Configure Nginx Reverse Proxy {#part-3}

sudo nano /etc/nginx/sites-available/vaultwarden
server {
    listen 80;
    server_name vault.yourdomain.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;

        proxy_set_header Upgrade    $http_upgrade;
        proxy_set_header Connection 'upgrade';

        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 notifications (required for real-time sync)
    location /notifications/hub {
        proxy_pass http://127.0.0.1:3012;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

    location /notifications/hub/negotiate {
        proxy_pass http://127.0.0.1:8080;
    }
}
sudo ln -s /etc/nginx/sites-available/vaultwarden /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

Part 4 — Enable HTTPS (Required) {#part-4}

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d vault.yourdomain.com

HTTPS is mandatory for Vaultwarden. The Bitwarden mobile apps and browser extensions will refuse to connect to an HTTP endpoint.


Part 5 — Initial Admin Setup {#part-5}

Visit https://vault.yourdomain.com.

  1. Create your account — use your actual email address
  2. Set a strong master password (this is the only password you need to remember)
  3. Log in and explore the vault interface

After creating your account, disable registration in .env:

SIGNUPS_ALLOWED=false
docker compose restart vaultwarden

This prevents anyone else from creating accounts on your server.


Part 6 — Connect Bitwarden Clients {#part-6}

Browser extensions

  1. Install the official Bitwarden browser extension (Chrome, Firefox, Safari, Edge)
  2. Click the extension icon
  3. Click the Settings gear (or Login page → More options)
  4. Self-hosted environment → Custom
  5. Server URL: https://vault.yourdomain.com
  6. Save, then log in with your credentials

Mobile apps (iOS/Android)

  1. Download the official Bitwarden app
  2. On the login screen → RegionSelf-hosted
  3. Server URL: https://vault.yourdomain.com
  4. Log in

Desktop app

Same process — find the server settings on the login screen and enter your server URL.


Part 7 — Configure Admin Panel {#part-7}

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

Enter the ADMIN_TOKEN from your .env file.

From here you can:

  • View all users and their email confirmation status
  • Send test emails
  • Configure global settings
  • Enable/disable features
  • Delete accounts

Useful admin settings:

Organizations: Enable (allows shared vaults between users)
Emergency Access: Enable (lets trusted contacts access your vault if needed)
Send: Enable (secure file/text sharing)

Part 8 — Backups (Critical) {#part-8}

Your password vault is critical data. Back it up frequently and to multiple locations.

nano ~/backup_vaultwarden.sh
#!/bin/bash
BACKUP_DIR=/home/ubuntu/backups/vaultwarden
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR

# Backup the entire Vaultwarden data volume
docker run --rm \
  -v vaultwarden_vaultwarden_data:/data \
  -v $BACKUP_DIR:/backup \
  alpine tar czf /backup/vaultwarden_$DATE.tar.gz -C /data .

# Keep 30 days of backups (passwords are important!)
find $BACKUP_DIR -name "vaultwarden_*.tar.gz" -mtime +30 -delete

echo "Vaultwarden backup: $DATE"
echo "Backup size: $(du -sh $BACKUP_DIR/vaultwarden_$DATE.tar.gz | cut -f1)"
chmod +x ~/backup_vaultwarden.sh

# Run twice daily (password vault is critical)
(crontab -l; echo "0 6,18 * * * ~/backup_vaultwarden.sh") | crontab -

Also export your vault manually periodically:

  1. In the Bitwarden web vault: Tools → Export Vault
  2. Export as encrypted JSON
  3. Store the export file offline (encrypted drive, etc.)

The Gotcha: HTTPS Is Not Optional {#gotcha}

Every Bitwarden client enforces HTTPS connections. Attempting to connect to an HTTP Vaultwarden instance results in:

  • Browser extension: "Connection failed: URL is not HTTPS"
  • Mobile app: refuses to connect
  • Web vault: most features disabled

Verify HTTPS is working before trying to connect clients:

curl -I https://vault.yourdomain.com
# Should return: HTTP/2 200

If you get a certificate error, fix Certbot before proceeding:

sudo certbot renew --force-renewal
sudo systemctl reload nginx

Security Best Practices {#security}

  1. Strong master password — 20+ characters, never reused
  2. Enable 2FA on your vault account — Settings → Two-step Login
  3. Disable registration after creating your account
  4. Restrict admin panel access via Nginx IP allowlist
  5. Keep Vaultwarden updateddocker compose pull && docker compose up -d
  6. Daily automated backups to offsite storage
  7. Use Fail2ban to limit brute-force attempts on the login endpoint
  8. Never expose the admin token — change it if it's ever compromised

Troubleshooting {#troubleshooting}

Issue Likely Cause Fix
Connection refused Service not running or wrong port Check systemctl status SERVICE and verify firewall rules
Permission denied Wrong file ownership or permissions Check file ownership with ls -la and use chown/chmod to fix
502 Bad Gateway Backend service not running Restart the backend service; check logs with journalctl -u SERVICE
SSL certificate error Certificate expired or domain mismatch Run sudo certbot renew and verify domain DNS points to server IP
Service not starting Config error or missing dependency Check logs with journalctl -u SERVICE -n 50 for specific error
Out of disk space Logs or data accumulation Run df -h to identify usage; clean logs or attach CBS storage
High memory usage Too many processes or memory leak Check with htop; consider upgrading instance plan if consistently high
Firewall blocking traffic Port not open in UFW or Lighthouse console Open port in Lighthouse console firewall AND sudo ufw allow PORT

Frequently Asked Questions {#faq}

Does Vaultwarden conflict with Lighthouse's console-level firewall?
No — they operate at different layers. Lighthouse's console firewall blocks at the network infrastructure level. Vaultwarden operates at the OS level. Both provide independent protection layers.

How do I check if Vaultwarden is working correctly?
Check the service status with sudo systemctl status vaultwarden. Review logs for recent activity. Most security tools have a test or dry-run mode to verify configuration.

What should I do if Vaultwarden blocks a legitimate user or IP?
Most security tools have a whitelist mechanism. Add trusted IPs to the whitelist/ignore list. For Fail2ban, use fail2ban-client set JAIL unbanip IP_ADDRESS.

How often should I review security logs?
For personal servers, a weekly review of auth logs and firewall logs is reasonable. For production or sensitive servers, set up log monitoring with alerts for suspicious patterns (unusually high fail rates, unusual hours).

Should I use all available security measures or just some?
Apply defense in depth: multiple independent layers. SSH key auth + Fail2ban + UFW + Lighthouse firewall + regular updates covers the most common attack vectors without significant complexity.

Self-host your password manager:
👉 Tencent Cloud Lighthouse — Secure VPS for sensitive applications
👉 View current pricing and promotions
👉 Explore all active deals and offers