Vaultwarden on Proxmox LXC: Self-Hosted Bitwarden-Compatible Password Manager

Deploy Vaultwarden (the lightweight Bitwarden-compatible server) in an unprivileged Proxmox LXC container with HTTPS, automatic backups, and mobile client access via Tailscale.

On this page
  1. Why Vaultwarden over self-hosted Bitwarden
  2. Architecture
  3. Task 1: Create the Vaultwarden container
  4. Task 2: Install Vaultwarden
  5. Task 3: Create your account and disable signups
  6. Task 4: Configure Bitwarden clients
  7. Task 5: Set up automatic backups
  8. Enabling 2FA on your vault

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.

Note

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

Bitwarden clientsBrowser · iOS · Androidvia TailscaleCT 111 · VaultwardenRust binary · port 8010.0.0.79SQLite / data dirvault DB + attachments/opt/vaultwarden/dataTailscaleremote access (no port forward)peira.dev

Task 1: Create the Vaultwarden container

First: make these values your own

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.

1Create CT 1115 min
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.

1Extract the Vaultwarden binary and web vault5 min
Inside CT 111 — extract from the official image

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.

2Create the vaultwarden system user2 min
Inside CT 111 — create service user

useradd -r -s /bin/false vaultwarden
chown -R vaultwarden:vaultwarden /opt/vaultwarden
3Create a TLS certificate3 min

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.

Inside CT 111 — self-signed certificate

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
Trusting the certificate

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.

4Create the environment configuration5 min
Create /opt/vaultwarden/.env

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.

Generate a real admin token

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.

5Create the systemd service3 min
Create /etc/systemd/system/vaultwarden.service

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
6Verify Vaultwarden is running2 min
Check service status

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

1Create your admin account3 min

On the Vaultwarden login page, click Create Account. Fill in your email and a strong master password.

Your master password cannot be recovered

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).

2Disable new account signups2 min

Once your account is created, disable open registration so no one else can create accounts:

Edit /opt/vaultwarden/.env

sed -i 's/SIGNUPS_ALLOWED=true/SIGNUPS_ALLOWED=false/' /opt/vaultwarden/.env
systemctl restart vaultwarden

Task 4: Configure Bitwarden clients

1Configure the browser extension2 min

In the Bitwarden browser extension (Chrome/Firefox/Edge):

  1. Click the extension icon
  2. Click the settings gear icon in the top-left
  3. Under Self-hosted environment, set Server URL to: https://10.0.0.79:8443
  4. Click Save

You can now log in with the account you created.

2Configure mobile clients2 min

On iOS/Android Bitwarden:

  1. Tap the region selector on the login screen
  2. Choose Self-hosted
  3. 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.
  4. Log in
Tip

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.

1Create a daily backup script5 min
Create /opt/vaultwarden/backup.sh

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
Schedule daily 3AM backup

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:

  1. Log into https://10.0.0.79:8443
  2. Go to Account Settings → Security → Two-step Login
  3. Enable Authenticator App
  4. 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.


Service management reference

# 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:

Sources: Vaultwarden (GitHub), Vaultwarden wiki, Bitwarden.

Comments

Comments are powered by GitHub Discussions — sign in with a GitHub account to join the conversation.