Wiunix Academy · October 21, 2025

Vaultwarden Self Hosted HTTPS: Secure Docker Setup with Nginx, TLS, and Admin Token

Deploy Vaultwarden on loopback, protect the admin token, proxy it safely, and prove recovery before storing real credentials.

Table of Contents

  1. Overview
  2. Prerequisites
  3. Quick Architecture
  4. Variables
  5. Step 1 — Install / Setup
  6. Step 2 — Base Configuration
  7. Step 3 — Enable & Health Checks
  8. Security / Hardening
  9. Performance & Optimization
  10. Backup & Restore
  11. Advanced Add-Ons
  12. Troubleshooting (Top issues)
  13. Key Takeaways & Next Steps

Overview

Deploy Vaultwarden Self Hosted HTTPS on Docker , WebSocket support, and an admin token. Per‑OS install commands are split; Add‑Ons are OS‑agnostic.

Prerequisites

Linux server with DNS to it; ports 80/443 open; sudo shell.

Quick Architecture

Clients → Nginx (TLS) → Vaultwarden → SQLite | Backups

Variables

Before you copy: Customize values once; then run source /root/vars.sh to load them for all steps.
  • VW_DOMAIN, EMAIL, VW_DATA, NGINX_SITE, VW_IMAGE, VW_ADMIN_TOKEN
sudo install -d -m 700 /root
cat <<'EOF' | sudo tee /root/vars.sh
export VW_DOMAIN="vault.example.com"
export EMAIL="[email protected]"
export VW_DATA="/var/lib/vaultwarden"
export NGINX_SITE="/etc/nginx/sites-available/vaultwarden.conf"
export VW_IMAGE="vaultwarden/server:latest"
export VW_ADMIN_TOKEN="$(openssl rand -hex 24)"
EOF
source /root/vars.sh

Step 1 — Install / Setup

Debian / Ubuntu
sudo apt update
sudo apt -y install docker.io nginx certbot   # Certbot install here (per‑OS)
RHEL / Rocky / Alma / CentOS Stream / Fedora
sudo dnf -y install docker nginx certbot      # Certbot install here (per‑OS)
Arch / Manjaro
sudo pacman -Syu --noconfirm docker nginx certbot   # Certbot install here (per‑OS)
openSUSE / SLE
sudo zypper refresh
sudo zypper install -y docker nginx certbot   # Certbot install here (per‑OS)

Step 2 — Base Configuration

sudo mkdir -p "$VW_DATA"
sudo docker run -d --name vaultwarden --restart unless-stopped   -p 127.0.0.1:8080:80   -v "$VW_DATA":/data   -e SIGNUPS_ALLOWED=true   -e ADMIN_TOKEN="$VW_ADMIN_TOKEN"   -e WEBSOCKET_ENABLED=true   "$VW_IMAGE"
Nginx TLS site (universal)
server {
  listen 80;
  server_name $VW_DOMAIN;
  location /.well-known/acme-challenge/ { root /var/www/_letsencrypt; }
  location / { return 301 https://$host$request_uri; }
}
server {
  listen 443 ssl http2;
  server_name $VW_DOMAIN;

  ssl_certificate     /etc/letsencrypt/live/$VW_DOMAIN/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/$VW_DOMAIN/privkey.pem;

  client_max_body_size 100m;
  proxy_set_header Host $host;
  proxy_set_header X-Forwarded-Proto https;
  proxy_set_header X-Real-IP $remote_addr;

  location /notifications/hub/negotiate { proxy_pass http://127.0.0.1:8080; }
  location /notifications/hub          { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_pass http://127.0.0.1:8080; }
  location / { proxy_pass http://127.0.0.1:8080; }
}

Step 3 — Enable & Health Checks

sudo systemctl enable --now docker nginx
sudo docker ps --format "table {{.Names}}	{{.Status}}	{{.Ports}}" | grep -E '^vaultwarden\b' || echo "vaultwarden not running?"
sudo ss -tlnp | grep -E ':(80|443)\b'  # Check

Security / Hardening

Harden with these practices; snippets are optional and separate:
  • Keep the app bound to 127.0.0.1:8080; all traffic goes through HTTPS Nginx.
  • Rotate the admin token regularly.
  • Restrict /admin to trusted IPs or a VPN.
Rotate admin token
export VW_ADMIN_TOKEN="$(openssl rand -hex 24)"
sudo docker stop vaultwarden && sudo docker rm vaultwarden
sudo docker run -d --name vaultwarden --restart unless-stopped   -p 127.0.0.1:8080:80   -v "$VW_DATA":/data   -e SIGNUPS_ALLOWED=true   -e ADMIN_TOKEN="$VW_ADMIN_TOKEN"   -e WEBSOCKET_ENABLED=true   "$VW_IMAGE"
Restrict /admin by IP
location /admin {
  allow 203.0.113.0/24;   # your office block
  deny  all;
  proxy_pass http://127.0.0.1:8080;
}

Performance & Optimization

  • Enable HTTP/2 (already enabled) and proxy keepalive.
  • Place data on SSD; monitor I/O latency (SQLite is file‑based).
  • Reduce client_max_body_size if attachments are disabled.

Backup & Restore

Back up both the app data and Nginx config. Store off‑server. Backup
sudo tar -C / -czf /root/vaultwarden-backup.tgz "$VW_DATA" "$NGINX_SITE"
ls -lh /root/vaultwarden-backup.tgz  # Check
Restore
sudo systemctl stop nginx
sudo docker stop vaultwarden
sudo tar -C / -xzf /root/vaultwarden-backup.tgz
sudo docker start vaultwarden
sudo systemctl start nginx
curl -s https://$VW_DOMAIN/ | head -n 1  # Check

Advanced Add-Ons

OS‑agnostic only.

(Add‑On) Automated Certificates (Certbot)

Use webroot ACME to request/renew certificates. Install Certbot per‑OS in Step 1; here we only run it.
sudo install -d -m 755 /var/www/_letsencrypt
sudo certbot certonly --webroot -w /var/www/_letsencrypt -d "$VW_DOMAIN" --email "$EMAIL" --agree-tos --no-eff-email
sudo certbot renew --dry-run  # Check

(Add‑On) SMTP Email

Enable email delivery for verification and invites.
sudo docker stop vaultwarden
sudo docker rm vaultwarden || true
sudo docker run -d --name vaultwarden --restart unless-stopped   -p 127.0.0.1:8080:80   -v "$VW_DATA":/data   -e SIGNUPS_ALLOWED=true   -e ADMIN_TOKEN="$VW_ADMIN_TOKEN"   -e WEBSOCKET_ENABLED=true   -e SMTP_HOST="smtp.example.com"   -e SMTP_FROM="$EMAIL"   -e SMTP_PORT=587   -e SMTP_SSL=true   -e SMTP_USERNAME="smtp-user"   -e SMTP_PASSWORD="smtp-password"   "$VW_IMAGE"

(Add‑On) Off‑server Backups (rclone to S3/MinIO)

Assumes rclone is installed and a remote (e.g., s3remote) is configured.
sudo tar -C / -czf /root/vaultwarden-$(date +%F).tgz "$VW_DATA"
rclone copy /root/vaultwarden-$(date +%F).tgz s3remote:backups/vaultwarden/  # Check

Troubleshooting (Top issues)

WebSocket not upgrading

grep -n "notifications/hub" "$NGINX_SITE"
sudo nginx -t && sudo systemctl reload nginx

Admin panel not accessible

sudo docker logs vaultwarden | tail -n 100 | sed -n '1,120p'

Key Takeaways & Next Steps

  • HTTPS + WebSocket + admin token ready.
  • Backups tested; optional add‑ons available.
  • Harden /admin, keep everything updated.