The fastest way to self-host Vaultwarden on a Raspberry Pi in 2026 is to run the vaultwarden/server:latest Docker image behind an Nginx reverse proxy with a Let's Encrypt TLS certificate — the entire stack takes roughly 45 minutes to configure on a Raspberry Pi 4 or Pi 5 running Raspberry Pi OS Lite (64-bit). Vaultwarden is an unofficial, community-maintained Bitwarden-compatible server written in Rust; it runs comfortably on 256 MB of RAM and is fully compatible with every official Bitwarden client app.
Prerequisites / What You'll Need
- Hardware: Raspberry Pi 4 (2 GB RAM minimum) or Raspberry Pi 5 — Pi 3 works but is not recommended for sustained performance
- OS: Raspberry Pi OS Lite 64-bit, released 2025-11-19 or later (based on Debian 12 Bookworm)
- Docker: Docker Engine 27.x (
docker --versionshould return 27.x.x) - Docker Compose: v2.27.0 or later (bundled with Docker Desktop; install
docker-compose-pluginon Pi) - Domain name: A domain you control with DNS A-record access — a free subdomain from DuckDNS works fine
- Port access: Ports 80 and 443 open and forwarded on your router to the Pi's local IP
- SSH access: Terminal session to the Pi (or a connected keyboard/monitor)
- Certbot: Will be installed during the guide
- Time: ~45 minutes, plus up to 24 hours if DNS propagation is slow
Step 1 — Update the System and Install Docker
SSH into your Pi and bring the system fully up to date before touching Docker. Stale packages are the leading cause of compose version mismatches I've seen in the field.
sudo apt update && sudo apt full-upgrade -y
sudo reboot
After the reboot, install Docker using the official convenience script:
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
Add your user to the docker group so you don't need sudo for every command:
sudo usermod -aG docker $USER
newgrp docker
Install the Compose plugin:
sudo apt install docker-compose-plugin -y
Verify: docker compose version should output Docker Compose version v2.27.0 or higher. If you see Command 'docker-compose' not found, you're using the old standalone binary — install the plugin as above.
Step 2 — Create the Directory Structure and Compose File
Keeping all Vaultwarden files under a single directory makes backups trivial:
mkdir -p ~/vaultwarden/vw-data
cd ~/vaultwarden
Create docker-compose.yml:
version: "3.8"
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: unless-stopped
environment:
DOMAIN: "https://vault.yourdomain.com"
SIGNUPS_ALLOWED: "false" # disable after creating your account
WEBSOCKET_ENABLED: "true"
LOG_LEVEL: "warn"
volumes:
- ./vw-data:/data
ports:
- "127.0.0.1:8080:80"
- "127.0.0.1:3012:3012" # WebSocket port
Gotcha: Setting SIGNUPS_ALLOWED: "false" before you create your first account will lock you out permanently. Leave it "true" until after you register, then set it back and restart the container.
Step 3 — Install Nginx and Certbot
Vaultwarden requires HTTPS — the Bitwarden clients refuse to connect over plain HTTP. Nginx acts as the TLS-terminating reverse proxy.
sudo apt install nginx certbot python3-certbot-nginx -y
Stop Nginx temporarily so Certbot can bind to port 80:
sudo systemctl stop nginx
Request a certificate (replace with your actual domain):
sudo certbot certonly --standalone -d vault.yourdomain.com
Certbot will write certificates to /etc/letsencrypt/live/vault.yourdomain.com/. Certificates expire in 90 days; Certbot installs a systemd timer that auto-renews them. Confirm the timer is active:
systemctl status certbot.timer
Expected output: Active: active (waiting) — if you see inactive (dead), enable it with sudo systemctl enable --now certbot.timer.
Step 4 — Configure the Nginx Reverse Proxy
Create a new Nginx site config:
sudo nano /etc/nginx/sites-available/vaultwarden
Paste the following (replace domain throughout):
server {
listen 80;
server_name vault.yourdomain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name vault.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/vault.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/vault.yourdomain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
client_max_body_size 128M;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /notifications/hub {
proxy_pass http://127.0.0.1:3012;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Enable the site and restart Nginx:
sudo ln -s /etc/nginx/sites-available/vaultwarden /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl start nginx
nginx -t must output syntax is ok and test is successful before you proceed.
Step 5 — Start Vaultwarden
cd ~/vaultwarden
docker compose up -d
Expected output:
[+] Running 2/2
✔ Network vaultwarden_default Created
✔ Container vaultwarden Started
Check logs to confirm the server is listening:
docker compose logs -f vaultwarden
Look for the line: INFO vaultwarden::api: Rocket has launched from http://0.0.0.0:80. Once you see it, navigate to https://vault.yourdomain.com in a browser.
Step 6 — Create Your Account and Harden the Installation
- Open
https://vault.yourdomain.comand click Create Account. - Use a strong master password — Vaultwarden enforces a minimum of 8 characters, but I recommend 20+ characters with mixed case, numbers, and symbols.
- After registering, enable two-step login under Account Settings → Security → Two-step Login. Vaultwarden supports TOTP (any authenticator app), email OTP, and FIDO2/WebAuthn hardware keys (YubiKey 5 series, Google Titan).
- Open
docker-compose.yml, changeSIGNUPS_ALLOWEDto"false", and apply:
docker compose up -d
Verification — Confirm Everything Is Working
| Check | What to look for |
|---|---|
| Browser | Padlock icon + valid TLS cert for your domain |
| Vaultwarden logs | INFO lines, no ERROR on startup |
| Bitwarden mobile app | Login succeeds using your custom server URL |
| WebSocket | Real-time sync works when you add an item on one device and it appears on another within ~5 seconds |
Run docker stats vaultwarden — idle RAM usage should be under 30 MB on a clean install with fewer than 500 vault items.
Recommended Tools: Managed Password Managers as a Fallback
Self-hosting is rewarding, but it comes with real operational responsibility: your backups, your uptime, your certificate renewals. If you're setting this up for family members or a small team that can't tolerate downtime, it's worth knowing what the managed alternatives cost and what they offer.
1Password — Best for Teams Who Want Audit Trails
1Password is headquartered in Toronto, Canada, subject to PIPEDA and Canadian privacy law. It encrypts vault data with AES-256-GCM and derives keys using PBKDF2-SHA256 with 650,000 iterations, plus a Secret Key architecture that means even 1Password's servers cannot decrypt your vault. It supports TOTP, WebAuthn/FIDO2, and hardware keys including YubiKey 5 series. Third-party audited by Cure53 (2022) and holds SOC 2 Type II certification. Supported platforms: Windows, macOS, Linux, iOS, Android, Chrome, Firefox, Edge, Safari.
Pricing: $2.99/user/month (Individual, billed annually), $4.99/user/month (Families, up to 5 users, billed annually), $7.99/user/month (Teams Starter, 10-seat minimum, billed annually), $19.95/user/month (Business, billed annually).
If your team grows beyond what one Pi can comfortably serve, 1Password is the managed option I'd move them to first — the Travel Mode and detailed activity log features are genuinely useful for small businesses. Our enterprise password manager roundup covers 1Password's admin controls in depth.
Try 1Password — 14-day free trial, no credit card required.
Keeper Security — Best for Regulated Industries
Keeper Security is headquartered in Chicago, Illinois, subject to US law. Vault data is encrypted with AES-256-GCM; key derivation uses PBKDF2-SHA256. MFA options include TOTP, SMS, RSA SecurID, Duo Security, and FIDO2/WebAuthn hardware keys. Keeper holds SOC 2 Type II certification and is FedRAMP Authorized — relevant if you're in healthcare or government. Supported platforms: Windows, macOS, Linux, iOS, Android, Chrome, Firefox, Edge, Safari.
Pricing: $4.99/user/month (Personal, billed annually), $6.24/user/month (Family, 5 users, billed annually), $4.99/user/month (Business Starter, 5-seat minimum, billed annually), $7.00/user/month (Business, billed annually), $8.75/user/month (Enterprise, billed annually).
Keeper Security is worth the mention here specifically because HIPAA-covered entities sometimes run into compliance questions with self-hosted vaults — see our best password manager for healthcare workers guide for a full breakdown.
Try Keeper Security — 30-day free business trial available.
Troubleshooting
Error: Error response from daemon: driver failed programming external connectivity
Port 80 or 8080 is already in use. Run sudo lsof -i :80 to identify the process, stop it, and restart the container.
Error: NET::ERR_CERT_AUTHORITY_INVALID in browser
Certbot didn't complete successfully, or you're accessing via IP instead of your domain. Confirm sudo certbot certificates shows a valid cert with a future expiry date. If the cert is missing, re-run the Certbot command from Step 3.
Error: [ERROR] Error sending email: Connection refused (if you enabled email 2FA)
Your SMTP settings in the docker-compose.yml environment block are incorrect or your email provider requires an app-specific password. Double-check SMTP_HOST, SMTP_PORT, SMTP_USERNAME, and SMTP_PASSWORD.
Bitwarden app shows "An error has occurred" when logging in
The app is still pointing at the default Bitwarden server. In the app, tap the gear icon on the login screen → Self-hosted environment → enter https://vault.yourdomain.com. The trailing slash matters on some app versions.
Container restarts in a loop / OOMKilled in docker inspect
Your Pi is running out of RAM. Check free -h — if available memory is under 100 MB, stop other containers or upgrade to a 4 GB Pi 4/Pi 5. Vaultwarden itself uses ~30 MB, but Nginx and the OS overhead add up on a 1 GB Pi 4.
FAQ
Is Vaultwarden secure enough for real password management?
Yes, with caveats. Vaultwarden uses the same AES-256-CBC client-side encryption as the official Bitwarden server — your master password never leaves your device, and all vault data is encrypted before transmission. However, Vaultwarden is not officially audited the way Bitwarden's cloud service is. You are also responsible for your own backup strategy, certificate renewal, and OS patching. If you maintain those operational practices, the cryptographic security is equivalent to Bitwarden's hosted offering. The risk is operational failure, not a weak encryption implementation.
Do I need a static IP address to self-host Vaultwarden?
No, but you do need a consistent way to reach your Pi from the internet. Most home ISPs issue dynamic IPs. The standard workaround is a Dynamic DNS (DDNS) service: DuckDNS is free and provides a subdomain like yourname.duckdns.org. Install the DuckDNS update script on the Pi (a simple cron job every 5 minutes) and point your Vaultwarden domain at it. Let's Encrypt will issue certificates for DuckDNS subdomains without any extra steps. Vaultwarden will be unreachable only during the brief window between your IP changing and the DDNS record updating — typically under 5 minutes.
What Bitwarden client apps work with Vaultwarden?
All official Bitwarden clients work with Vaultwarden by pointing them at your custom server URL. This includes: Bitwarden for Windows, macOS, and Linux (desktop apps), Bitwarden for iOS and Android, the browser extension for Chrome, Firefox,