August 23, 2026
Vaultwarden: Bitwarden Compatibility on Your Own Server
Deployment notes for Vaultwarden, a lightweight self-hosted password manager server compatible with official Bitwarden clients: architecture, Docker Compose setup, HTTPS requirements, SQLite WAL backup strategy, and limitations.
Vaultwarden is an alternative implementation of the Bitwarden server written in Rust: a single lightweight binary compatible with official Bitwarden clients. Deployment and evaluation notes, not a claim that it replaces every credential-management need.
Why run your own Bitwarden server
The official Bitwarden cloud is convenient — clients are genuinely good — but three things rankle: data still lives on a third-party server even though the vault is encrypted; TOTP, attachments, and organizations require a premium subscription; and the official server is resource-heavy and .NET-based, expensive to self-host. Vaultwarden addresses all three: compatible with every official client (browser extension, iOS/Android apps, desktop), lightweight — RAM typically below 50 MB — and premium features free. The selling point is compatibility: the clients stay the same, only the server URL changes.
Architecture: a single Rust binary behind the Bitwarden API
Vaultwarden implements the Bitwarden Client API almost completely in one Rust binary, with SQLite as the default database backend; the bundled web vault is an official Bitwarden build with patches, so the browser UI is identical to bitwarden.com. Data is encrypted client-side; the server only stores ciphertext and never receives the master password. All data lives in one directory: db.sqlite3 (plus -wal/-shm), attachments/, sends/, config.json, and rsa_key.* files for auth tokens. WebSocket live-sync for browser/desktop is on by default since v1.29 and runs on the main HTTP port since v1.31 (port 3012 is gone); mobile uses FCM/APNs push requiring credentials from Bitwarden’s cloud.
Deployment with Docker Compose
This is the Compose setup used:
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: unless-stopped
environment:
- WEBSOCKET_ENABLED=true
volumes:
- ./vw-data:/data
ports:
- "8008:80"
The ./vw-data volume holds all persistent data; port 8008 is published from the container’s port 80. Behind a reverse proxy, set the DOMAIN environment variable to the public URL. Note: WEBSOCKET_ENABLED is deprecated since v1.29 — WebSocket is on by default, just ensure the proxy forwards Upgrade/Connection headers. The image runs as root by default; add user: "1000:1000" for least privilege.
HTTPS is mandatory, plus admin panel hardening
HTTPS is not optional: the web vault needs the Web Crypto API, which browsers only expose in secure contexts, and clients refuse plain HTTP except on localhost. The recommended path is a TLS-handling reverse proxy — Caddy, Nginx Proxy Manager, Traefik, Cloudflare Tunnel, or Tailscale HTTPS — with Let’s Encrypt or Cloudflare origin certificates. Built-in TLS via ROCKET_TLS is not recommended: immature, no ECC, no strict SNI. Mobile apps need correct OCSP stapling; self-signed or incomplete chains break login on many devices.
The admin panel at /admin only becomes active once ADMIN_TOKEN is set. Use a long random string (e.g. openssl rand -base64 32), ideally argon2id-hashed via vaultwarden hash, and enable it only after HTTPS is in place. Public registration is on by default: set SIGNUPS_ALLOWED=false for a private instance; consider fail2ban for brute force.
Backing up the SQLite WAL database
Nearly all vault data lives in db.sqlite3 inside /data. WAL mode makes direct copies while the container runs risky; the documented approach is the sqlite3 CLI’s .backup command (Online Backup API) or VACUUM INTO, or the built-in docker exec vaultwarden /vaultwarden backup since v1.32.1. The images ship no sqlite3 binary or cron, so schedule backups on the host.
Do not forget attachments/ (files outside the database), config.json (admin token and SMTP credentials in plaintext), and rsa_key.* (loss forces every user to log in again). Backups should be encrypted — e.g. a Duplicati repository — with at least one copy off-host. When restoring, stop the container first and delete any stale -wal file.
Limitations worth knowing
- Not an official Bitwarden project. Maintained by volunteers with no release schedule; bugs cannot be reported to Bitwarden support.
- Feature parity is not 100%. The Public API is only partial (Directory Connector), passkey login is in progress, and New Device Login Protection, custom roles, and some enterprise policies are missing; SSO and directory sync are not a priority.
- Mobile clients still touch Bitwarden’s cloud. FCM/APNs push needs credentials from Bitwarden’s cloud — a trade-off if going fully Bitwarden-free.
- Sensitive to TLS configuration. Self-signed or incomplete chains break client connections; mobile requires correct OCSP stapling.
- Single failure domain. Server down means the vault is unreachable until it recovers; off-host backups remain mandatory, and a lost master password means nobody can open the data.
Conclusion
For a single-machine homelab comfortable with the Bitwarden client ecosystem, Vaultwarden is a rational choice: full client compatibility, small footprint, premium features without a subscription. The trade-offs are clear — an unofficial project with missing features, mobile push tied to Bitwarden’s cloud, and TLS that must be right. With encrypted backups and an off-host copy, it is an honest foundation for credential management.
