Skip to content
Josh Forrest
Go back

Self-hosting Vaultwarden: my passwords on my hardware

Table of contents

Open Table of contents

Why self-host this, of all things

A password manager is the single most sensitive piece of software in most people’s lives. It’s the one thing that, if it gets compromised, every other account you own gets compromised at the same time. It’s also, for that exact reason, the thing most people are nervous about self-hosting - and rightly so. Getting it wrong is much worse than getting your photo gallery wrong.

So why do it?

For me, it came down to two things:

  1. Trust. Cloud password managers have a pretty strong track record of being well-engineered, but the last few years have shown that even the best of them get breached eventually. When that happens, every customer’s encrypted vault is in the hands of whoever did the breaching, and the only thing standing between them and your passwords is the strength of your master password. If I’m trusting something, I’d rather trust a server I can see and control.
  2. Cost. Mostly a side benefit, but Bitwarden’s premium tier is a few quid a month, and Vaultwarden gives you the equivalent feature set for free. Over years, that adds up.

The thing that makes this realistic is Vaultwarden - an open-source, drop-in compatible reimplementation of the Bitwarden server, written in Rust, that runs comfortably in a tiny LXC container. It speaks the same API as the real Bitwarden server, which means all the official Bitwarden client apps - browser extensions, mobile apps, desktop apps - work with it unmodified. You’re not running a janky alternative client, you’re running the real Bitwarden clients against your own server.

Where it runs

Vaultwarden lives in an LXC container on proxmox2 at 10.10.20.16, listening on port 8000, sitting on the container VLAN like the rest of my services. It’s a small, single-purpose container - Vaultwarden itself, a SQLite database for the vault, and that’s it. Resource usage is essentially zero; it idles below 1% CPU and uses a few hundred MB of RAM.

The data that actually matters - the vault itself - is encrypted at rest using a key derived from my master password, the same way Bitwarden’s official server stores it. Even if someone got root on the LXC and copied the database file, they’d still need my master password to decrypt anything inside it. That’s the layer of security that makes self-hosting a password manager defensible: the server stores ciphertext, not plaintext, and the decryption key never leaves the client devices.

How it’s exposed

Vaultwarden has to be reachable from outside my home network. The whole point of a password manager is that it works on every device, everywhere - phone, laptop, in the office, on holiday - and a password manager that only works on my home Wi-Fi would be useless.

I expose it via a Cloudflare Tunnel at vault.jtforrest.com. A dedicated LXC container (cloudflared, CT 105) maintains a persistent outbound connection to Cloudflare’s edge - no inbound ports, no VPS required. From the outside, the flow is:

  1. Browser extension or mobile app connects to vault.jtforrest.com
  2. Cloudflare terminates TLS, sits in front as a layer of protection (rate limiting, basic WAF, the lot)
  3. Cloudflare routes the request down the tunnel into my homelab
  4. The tunnel exits at the Vaultwarden LXC at 10.10.20.16:8000
  5. Vaultwarden responds back the same way

There is no inbound port open on my home router. My home IP is never exposed. If someone wanted to attack the Vaultwarden instance directly, they’d have to first get past Cloudflare’s edge, which is meaningfully harder than scanning a residential IP range for open ports.

I use a Cloudflare Tunnel here specifically - rather than the edge VPS approach I use for Immich and Plex - because Vaultwarden’s traffic is low-bandwidth API calls and sync operations. There’s no file upload concern, so the Cloudflare free plan works perfectly and removes the need to manage another piece of infrastructure.

If Cloudflare goes down, the worst-case scenario is that I temporarily can’t reach my passwords from outside my house - annoying, but not catastrophic, because the Bitwarden clients cache the vault locally and continue to work offline.

The security thinking

This is the bit that matters most, and it’s the bit that took the most thought before I committed to running this.

The threat model for self-hosting a password manager is genuinely different from self-hosting most other services. With photos or media, the worst case is “someone gets my files,” which is bad but bounded. With passwords, the worst case is “someone gets a foothold into every other account I own,” which is unbounded and catastrophic. So the security thinking has to be tighter.

A few things I do (or rely on) specifically because it’s Vaultwarden:

The honest summary: self-hosting Vaultwarden is defensible if you take the security side seriously, but it’s not the right choice for everyone. If you’re not going to put thought into the master password, the 2FA, the backups, and the network exposure, you’re better off with a hosted Bitwarden or 1Password subscription. The convenience of a managed service is worth it if the alternative is doing self-hosting badly.

What I learned

What’s next

If you’re thinking about self-hosting your password manager: do it, but do it carefully. It’s the service where it’s most worth it to slow down and think about security from the start.


Share this post on:

Previous Post
Self-hosting Plex: media at home, exposed via a VPS
Next Post
Self-hosting AdGuard Home: network-wide ad blocking with no single point of failure