Why Run Your Own Password Vault?
Bitwarden is excellent software. But trusting any third-party service with every password you own means accepting that their servers, their security practices, and their business decisions are all outside your control. Vaultwarden sidesteps that entirely. It is an unofficial, open-source reimplementation of the Bitwarden server API, written in Rust, designed to run on hardware you own – a home server, a VPS, a Raspberry Pi. You get the full Bitwarden client experience, including browser extensions, mobile apps, and desktop clients, all talking to a server you control.
The setup is not complicated, but it does require Docker, a domain name with a valid SSL certificate, and a small amount of comfort with the command line. This guide walks through the entire process: getting Vaultwarden running, securing it with HTTPS, and making it accessible from any device. If you already use Docker for other self-hosted projects – say, something like Homebox for home inventory tracking – the workflow here will feel immediately familiar.

Prerequisites and System Requirements
Before pulling any Docker images, make sure your environment is ready. You need Docker and Docker Compose installed on a Linux host. Vaultwarden itself is extremely lightweight – it runs comfortably on 512MB of RAM and a single CPU core – so even a low-end VPS or an old Raspberry Pi 4 will handle it without strain. You also need a domain name or subdomain pointed at your server’s IP address. Running Vaultwarden over plain HTTP is technically possible for local-only use, but the official Bitwarden clients require HTTPS for almost everything, including vault sync. A valid SSL certificate is not optional in practice.
The cleanest approach uses a reverse proxy – Caddy or Nginx Proxy Manager are both popular choices – to handle HTTPS termination in front of Vaultwarden. Caddy is particularly low-friction because it handles Let’s Encrypt certificate issuance and renewal automatically with almost no configuration. This guide uses Caddy as the reverse proxy. If you already have Nginx running, the same logic applies; only the config syntax changes.

Installing and Configuring Vaultwarden
Start by creating a directory for the project and writing a docker-compose.yml file. The core service definition is straightforward. Pull the vaultwarden/server:latest image, map port 80 internally, mount a volume for persistent data, and set a handful of environment variables. The most important variable is DOMAIN, which must be set to your full HTTPS URL (for example, https://vault.yourdomain.com). Without this, certain features like web vault access and attachment uploads will not work correctly.
For the database, Vaultwarden defaults to SQLite, which is perfectly adequate for personal or small-team use. If you expect dozens of concurrent users or want a more production-grade setup, you can configure it to use MySQL or PostgreSQL by setting the DATABASE_URL environment variable. For most self-hosters, SQLite with a regular backup routine is the right call – simpler, fewer moving parts, and the performance ceiling is higher than most people will ever reach.
The environment variable SIGNUPS_ALLOWED deserves special attention. It defaults to true, which means anyone who reaches your Vaultwarden URL can create an account. Unless you want an open registration server, set this to false immediately after creating your own account. You can also set INVITATIONS_ALLOWED=false to lock down organization invitations. If you want to allow specific people to register without opening it to the world, Vaultwarden supports an admin panel that lets you send individual invite links – enable it by setting ADMIN_TOKEN to a strong random string.
Here is a minimal working docker-compose.yml to get started:
- image: vaultwarden/server:latest
- volumes: ./vw-data:/data
- environment: DOMAIN, SIGNUPS_ALLOWED, ADMIN_TOKEN
- restart: unless-stopped
- network: shared proxy network so Caddy can reach it
Run docker compose up -d and confirm the container starts cleanly with docker compose logs -f. You should see Vaultwarden announce which features are active and confirm the database has initialized. At this point the service is running but not yet accessible from the internet.
Setting Up HTTPS with Caddy
If Caddy is not already running, add it as a second service in the same Docker Compose file or in a separate stack, depending on how you manage your reverse proxy. The key requirement is that both Caddy and Vaultwarden share the same Docker network so Caddy can route traffic to Vaultwarden by container name.
The Caddyfile configuration for Vaultwarden is minimal. Point your subdomain at the Vaultwarden container name and port, and Caddy handles everything else – certificate issuance, renewal, HTTP to HTTPS redirects. One detail that catches people: Vaultwarden’s WebSocket notifications for real-time vault sync require you to proxy the /notifications/hub path separately, passing the Upgrade header correctly. Without this, the vault still works but live sync between clients does not update instantly – you will notice a delay before changes on one device appear on another.
Connecting Clients and Staying Secure
Once the server is running and HTTPS is confirmed working (visit your domain in a browser and check the certificate), connecting any Bitwarden client is a one-step change. In the Bitwarden browser extension, mobile app, or desktop client, open the settings and switch the server URL from the default Bitwarden cloud address to your own domain. Log in with the account you created, and the client syncs against your server from that point forward.
A few security practices are worth building in from day one. Enable two-factor authentication on your vault account immediately – Vaultwarden supports TOTP authenticator apps, email codes, and hardware keys via WebAuthn. Schedule automated backups of the vw-data directory to an offsite location; the entire vault, attachments, and configuration live there. If that directory is lost without a backup, so is every credential inside it. A daily rclone job pushing an encrypted copy to object storage costs almost nothing and takes ten minutes to configure.
Keep the Vaultwarden image updated regularly. The project moves quickly and security patches do land between releases. A simple approach is to run docker compose pull followed by docker compose up -d on a monthly schedule, or subscribe to the Vaultwarden GitHub releases feed so you know when a new version drops. The admin panel, accessible at /admin with your token, shows the current version and gives you a read on active users, failed login attempts, and pending invitations – enough visibility to spot something unusual before it becomes a problem.

Handling Edge Cases
A few scenarios trip up first-time installers. If the Bitwarden mobile app refuses to connect even though the browser extension works, confirm that your server’s SSL certificate is issued by a publicly trusted CA – self-signed certificates will cause the app to reject the connection silently on most mobile operating systems. Let’s Encrypt certificates issued through Caddy are publicly trusted, so this is only a problem if you went off-script with a custom CA.
If you want Vaultwarden accessible only from within your home network or via VPN rather than the open internet, the configuration changes are minimal: remove the public DNS record, run Caddy with a local-only certificate via a split-horizon DNS setup, and restrict the firewall accordingly. This trades convenience for a smaller attack surface – the vault is simply unreachable from outside your network. Either approach is valid depending on your threat model, but the local-only setup does mean you cannot sync new credentials when you are away from home without a VPN connection already established.





