Self-host Bitwarden — Docker compose walkthrough
Bitwarden's server is open source. You can run the entire stack — vault API, identity service, admin portal, MS SQL — on your own VPS, NAS, or homelab. This page walks through the official "unified" Docker install (released 2024), the older multi-container layout, and the popular Vaultwarden community fork.
Three reasons people choose self-hosting: regulatory (vault must stay inside specific jurisdiction), zero-trust paranoia (you don't want any third party — even Bitwarden — to hold your encrypted ciphertext), and cost at scale (large orgs save on per-seat pricing). For one-person personal use, the cloud free tier is genuinely fine; self-host is mostly a values choice.
Why bother
The Bitwarden cloud is end-to-end encrypted — Bitwarden Inc. cannot read your vault, ever. So the threat model improvement from self-hosting isn't "they could read my data" — it's:
- Availability: if Bitwarden's cloud has an outage, your self-hosted instance keeps working.
- Data residency: some jurisdictions or compliance regimes require vault data to stay on-prem or in a specific region.
- Zero-trust: you don't even want encrypted-at-rest data on a third party's infrastructure.
- Cost: large organisations with hundreds of seats can save vs Enterprise SaaS pricing — though self-host has its own ops cost.
- Hobby/learning: running the full stack is genuinely educational — auth, encryption, sync protocols all in plain Docker compose.
Server requirements
- OS: Linux (any modern distro — Debian/Ubuntu, RHEL/Fedora, Arch, Alpine).
- RAM: 2 GB minimum for unified install, 4 GB for the multi-container "full" install. Vaultwarden runs on 256 MB.
- Disk: 25 GB free (database + attachments + backups).
- CPU: 2 vCPU is fine for personal/family use, 4+ for small org.
- Docker + Docker Compose: recent versions.
docker --version≥ 20.10. - Domain: a real domain name (or sub-domain) with DNS pointing at the server. Self-signed isn't supported by all clients.
- TLS certificate: Let's Encrypt is the standard path; the install script can request one for you.
A $5/month VPS (Hetzner CX11, DigitalOcean basic droplet, Vultr starter) is enough for personal use. For an organisation of 50+ users, scale up to ~$20-40/month.
Three install paths — pick one
| Path | For | Containers | RAM |
|---|---|---|---|
| Unified (official, 2024+) | Most users — single docker-compose file | 1 image, 1 container | ~1.5 GB |
| Multi-container (legacy) | Enterprise needing horizontal scale | ~12 separate containers | ~4 GB |
| Vaultwarden (community fork) | Tiny servers, RPi, hobby use | 1 container (Rust) | ~256 MB |
Path 1: Unified install (recommended)
Bitwarden's "unified" Docker image bundles everything — vault, identity, admin, database — into a single container. Released in 2024; significantly easier than the previous multi-container setup.
Step 1: Install Docker
# Ubuntu/Debian
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
# Log out and back in for group change to take effect
Step 2: Get a Bitwarden install ID and key
Visit bitwarden.com/host, enter your email — Bitwarden emails you an installation ID and installation key. These authorise your self-hosted instance to talk to Bitwarden's licence server. Free for personal/family use.
Step 3: Pull and run the unified image
mkdir -p ~/bitwarden && cd ~/bitwarden
# Create environment file
cat > settings.env <<'EOF'
BW_DOMAIN=vault.your-domain.com
BW_DB_PROVIDER=sqlite
BW_INSTALLATION_ID=<from email>
BW_INSTALLATION_KEY=<from email>
EOF
# Pull and run
docker run -d \
--name bitwarden \
--restart unless-stopped \
--env-file settings.env \
-p 80:8080 \
-p 443:8443 \
-v ~/bitwarden:/etc/bitwarden \
bitwarden/self-host:beta
Step 4: Configure TLS
For production, put a reverse proxy (Caddy, Traefik, nginx) in front of the container handling Let's Encrypt automatically. Caddy example:
# /etc/caddy/Caddyfile
vault.your-domain.com {
reverse_proxy localhost:8080
}
Caddy auto-fetches the certificate from Let's Encrypt on first request. Done.
Step 5: First sign-in
Open https://vault.your-domain.com in a browser. The Bitwarden web vault is up. Click Create account for the first user — that user becomes the admin. Configure the rest from /admin.
Path 3: Vaultwarden (community fork)
Vaultwarden is an unofficial Rust reimplementation of the Bitwarden server. Speaks the same API (so all official Bitwarden clients work against it), but uses 1/10th the memory and runs on Raspberry Pi-class hardware. Not endorsed by Bitwarden Inc. but tolerated; many self-hosters prefer it.
docker run -d \
--name vaultwarden \
-e DOMAIN=https://vault.your-domain.com \
-v vw-data:/data \
-p 80:80 \
vaultwarden/server:latest
Then put Caddy/nginx/Traefik in front for TLS — same as unified install.
Vaultwarden trade-offs:
- ✅ Tiny memory footprint (256 MB)
- ✅ Fast (Rust)
- ✅ Single binary, single container
- ❌ Not officially supported — bug fixes lag behind upstream
- ❌ Some Bitwarden Inc. paid features (Duo SSO, advanced KMS) not implemented
- ❌ Won't work for Bitwarden Inc. business contracts that require official server
TLS setup
You need real TLS. Self-signed certificates work for desktop clients (with effort) but mobile apps and the browser extension reject them. Three reverse-proxy options:
Caddy (easiest)
Two lines of Caddyfile auto-fetches the cert. Best choice if you have no existing reverse proxy.
Traefik
Good if you already use Traefik for other Docker workloads. Add labels to the bitwarden container, Traefik handles the routing and TLS automatically.
nginx + certbot
Traditional choice. nginx config plus certbot for cert renewal. More verbose than Caddy, more flexible if you need custom routing.
Backups
The unified install stores everything under /etc/bitwarden/ on the host. Back that directory up daily:
# Stop the container briefly for consistent snapshot
docker stop bitwarden
tar czf bw-backup-$(date +%F).tar.gz ~/bitwarden/
docker start bitwarden
# Send off-site (rclone, restic, borg, your choice)
restic backup ~/bitwarden/
Critical: backup test once a month. Set a calendar reminder; restore the most recent backup to a test directory and verify Bitwarden launches against it.
Updates
docker pull bitwarden/self-host:beta
docker stop bitwarden
docker rm bitwarden
# Re-run docker run command from above
Bitwarden ships server updates monthly. Vaultwarden ships more frequently. For both, watch the GitHub Releases page (or RSS) so you don't miss security patches.
Related resources
Self-hosting touches every other Bitwarden topic — once you control the server, security, pricing, client setup and the comparison-with-cloud question all look different. The pages below cover the surrounding decisions: