On this page
Bitwarden is the gold-standard open-source password manager. Vaultwarden is an unofficial, lightweight Rust implementation of the Bitwarden server API — it runs on a fraction of the resources and is fully compatible with all official Bitwarden clients (browser extensions, iOS, Android, desktop apps).
Running it yourself means your vault never touches a cloud server — the encrypted database sits on hardware you own, in a container you control. And because Bitwarden’s architecture encrypts everything client-side with your master password, even your own server never sees a plaintext credential. Combined with Tailscale for remote access, this setup gives you the convenience of a hosted password manager with complete data sovereignty.
Why Vaultwarden over self-hosted Bitwarden
Bitwarden’s official self-hosted server is a multi-container Docker stack that requires at least 2 GB RAM and a modern CPU. Vaultwarden is a single Rust binary that runs in 50 MB RAM and has been audited by the security community for years.
Vaultwarden was formerly named Bitwarden_RS. It is not officially affiliated with Bitwarden, Inc., but implements the same API spec. All official Bitwarden clients work with it — the connection URL is the only thing that changes.
Architecture
Task 1: Create the Vaultwarden container
Example values below: container ID 111, IP 10.0.0.79, node name pvelab04, and CHANGE_ME_USE_openssl_rand_base64_48 (generate a real token and keep it in a password manager). If a value looks specific to one machine, it’s a placeholder to change — not a literal to copy.
| Field | Value |
|---|---|
| VMID | 111 |
| Hostname | vaultwarden |
| OS | Ubuntu 24.04 LXC (unprivileged) |
| IP | 10.0.0.79 (static) |
| Cores | 1 |
| RAM | 256 MB |
| Disk | 5 GB |
Vaultwarden is unusually lightweight. 256 MB RAM is genuinely sufficient for a single-household vault.
Task 2: Install Vaultwarden
Vaultwarden does not publish standalone binaries on its releases page; the project ships Docker images. Its wiki documents the supported way to get a native binary anyway: extract it from the official Alpine image. The binary is statically linked, so it runs directly in this container with no Docker and no Rust toolchain.
apt-get update && apt-get install -y curl openssl
# Vaultwarden wiki method: pull the official image's layers without Docker
mkdir -p /tmp/vw-image && cd /tmp/vw-image
curl -fsSLO https://raw.githubusercontent.com/jjlin/docker-image-extract/main/docker-image-extract
chmod +x docker-image-extract
./docker-image-extract vaultwarden/server:latest-alpine
# Install the server binary and the web vault UI
mkdir -p /opt/vaultwarden/data
cp output/vaultwarden /opt/vaultwarden/
cp -r output/web-vault /opt/vaultwarden/
/opt/vaultwarden/vaultwarden --version
The last command prints the version, for example Vaultwarden 1.37.3. To upgrade later, rerun the extraction, stop the service, copy the two items over the old ones, and start it again.
useradd -r -s /bin/false vaultwarden
chown -R vaultwarden:vaultwarden /opt/vaultwarden
The Bitwarden web vault only works over HTTPS. It encrypts your vault in the browser with the Web Crypto API, and browsers only expose that API on secure origins (HTTPS or localhost). Over plain HTTP the page loads, but account creation and login fail. Vaultwarden can serve TLS itself, so a certificate is all this step needs.
mkdir -p /opt/vaultwarden/tls
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \
-keyout /opt/vaultwarden/tls/server.key \
-out /opt/vaultwarden/tls/server.crt \
-subj "/CN=vaultwarden.homelab.lan" \
-addext "subjectAltName=DNS:vaultwarden.homelab.lan,IP:10.0.0.79"
chown -R vaultwarden:vaultwarden /opt/vaultwarden/tls
chmod 600 /opt/vaultwarden/tls/server.key
A self-signed certificate must be trusted on each device that opens the vault: import server.crt into the operating system’s certificate store. The self-signed TLS playbook covers the details. If you’d rather every device trust it automatically, put Vaultwarden behind a reverse proxy with a Let’s Encrypt certificate instead, as in the Traefik guide.
cat > /opt/vaultwarden/.env << 'EOF'
# Data directory
DATA_FOLDER=/opt/vaultwarden/data
# Web vault UI
WEB_VAULT_FOLDER=/opt/vaultwarden/web-vault
WEB_VAULT_ENABLED=true
# HTTPS on port 8443, using the certificate from step 3
ROCKET_ADDRESS=0.0.0.0
ROCKET_PORT=8443
ROCKET_TLS={certs="/opt/vaultwarden/tls/server.crt",key="/opt/vaultwarden/tls/server.key"}
# The URL clients use to reach the vault
DOMAIN=https://10.0.0.79:8443
# Enable signups only for initial setup — DISABLE AFTER CREATING YOUR ACCOUNT
SIGNUPS_ALLOWED=true
# Admin token (generate with: openssl rand -base64 48)
ADMIN_TOKEN=CHANGE_ME_USE_openssl_rand_base64_48
# Log level
LOG_LEVEL=warn
EOF
chown vaultwarden:vaultwarden /opt/vaultwarden/.env
chmod 600 /opt/vaultwarden/.env
Port 8443 is used because a non-root service cannot bind ports below 1024 without extra capabilities.
Run openssl rand -base64 48 and replace CHANGE_ME_USE_openssl_rand_base64_48 in the .env file. This token protects the Vaultwarden admin panel — treat it like a password.
cat > /etc/systemd/system/vaultwarden.service << 'EOF'
[Unit]
Description=Vaultwarden Password Manager
After=network.target
[Service]
User=vaultwarden
Group=vaultwarden
WorkingDirectory=/opt/vaultwarden
EnvironmentFile=/opt/vaultwarden/.env
ExecStart=/opt/vaultwarden/vaultwarden
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
systemctl enable --now vaultwarden
systemctl status vaultwarden
curl -k https://127.0.0.1:8443/alive
# Prints a timestamp when the server is up
Open https://10.0.0.79:8443 in a browser that trusts your certificate. You should see the Vaultwarden web vault login page.
Task 3: Create your account and disable signups
On the Vaultwarden login page, click Create Account. Fill in your email and a strong master password.
Vaultwarden does not have a password reset mechanism. If you forget your master password, your vault is permanently locked. Use a strong, memorable passphrase and store it somewhere offline (written on paper in a secure location).
Once your account is created, disable open registration so no one else can create accounts:
sed -i 's/SIGNUPS_ALLOWED=true/SIGNUPS_ALLOWED=false/' /opt/vaultwarden/.env
systemctl restart vaultwarden
Task 4: Configure Bitwarden clients
In the Bitwarden browser extension (Chrome/Firefox/Edge):
- Click the extension icon
- Click the settings gear icon in the top-left
- Under Self-hosted environment, set Server URL to:
https://10.0.0.79:8443 - Click Save
You can now log in with the account you created.
On iOS/Android Bitwarden:
- Tap the region selector on the login screen
- Choose Self-hosted
- Set Server URL to
https://10.0.0.79:8443(the address in your certificate). Away from home, the Tailscale subnet router makes that same address reachable. The phone must trust your certificate first; see the note in Task 2. - Log in
For mobile access outside your LAN without port forwarding, install Tailscale on your phone. The Vaultwarden container’s host node (pvelab04) is a Tailscale node, so you can reach https://10.0.0.79:8443 from anywhere your phone has Tailscale running — no public exposure needed.
Task 5: Set up automatic backups
The entire Vaultwarden state is in /opt/vaultwarden/data/. Back up this directory and you have everything.
cat > /opt/vaultwarden/backup.sh << 'EOF'
#!/bin/bash
BACKUP_DIR="/opt/vaultwarden/backups"
DATE=$(date +%Y%m%d_%H%M)
mkdir -p "$BACKUP_DIR"
# Stop Vaultwarden to ensure a clean SQLite backup
systemctl stop vaultwarden
tar czf "$BACKUP_DIR/vault_$DATE.tar.gz" -C /opt/vaultwarden data/
systemctl start vaultwarden
# Keep last 14 backups
find "$BACKUP_DIR" -name "vault_*.tar.gz" -mtime +14 -delete
echo "Backup complete: $BACKUP_DIR/vault_$DATE.tar.gz"
EOF
chmod +x /opt/vaultwarden/backup.sh
echo "0 3 * * * /opt/vaultwarden/backup.sh >> /var/log/vaultwarden-backup.log 2>&1" | crontab -
Enabling 2FA on your vault
Vaultwarden supports TOTP-based 2FA (Google Authenticator, Bitwarden Authenticator, Aegis, etc.). Enable it in the Bitwarden web vault:
- Log into
https://10.0.0.79:8443 - Go to Account Settings → Security → Two-step Login
- Enable Authenticator App
- Scan the QR code with your TOTP app
After enabling 2FA, even if someone knows your master password, they cannot access your vault without the TOTP code.
# View logs
journalctl -u vaultwarden -f
# Restart after config change
systemctl restart vaultwarden
# Check data directory size
du -sh /opt/vaultwarden/data/
# List backups
ls -lh /opt/vaultwarden/backups/
Related posts:
- Proxmox LXC Networking: Bridges, VLANs, and Static IPs — assign a static IP to this container
- Proxmox Firewall Guide — isolate Vaultwarden at the CT level so only trusted IPs can reach it
- Proxmox Security Hardening — harden the host node running this container
- Tailscale Subnet Router: Remote Access to Your Entire Homelab — access your vault remotely without exposing it to the internet
- Proxmox Backup Server: Automated Container Backups — back up the vault data directory automatically
- What Is Authentik? — the identity provider that complements a password manager with single sign-on
Sources: Vaultwarden (GitHub), Vaultwarden wiki, Bitwarden.
Comments
Comments are powered by GitHub Discussions — sign in with a GitHub account to join the conversation.