Two Years of Vaultwarden on Proxmox: What Worked, What Didn’t, and How to Keep It Running Smoothly
- Nishadil
- May 18, 2026
- 0 Comments
- 6 minutes read
- 6 Views
- Save
- Follow Topic
Running Vaultwarden in a Proxmox VM – a two‑year run‑through, from initial setup to backups, updates, and the little hiccups along the way
I’ve been hosting Vaultwarden on a Proxmox server for two years. Here’s a candid walk‑through of the hardware, the Docker‑based install, backup tricks, update routines, and the lessons I’ve learned.
When I first heard about Vaultwarden – the lightweight, open‑source fork of Bitwarden – I figured it would be a perfect fit for my modest home lab. I already had a Proxmox VE host humming away with a couple of VMs, so I thought, why not spin up a small Debian VM and let it handle my passwords?
Fast‑forward two full years, and that little VM is still alive, serving my family’s vaults, surviving a few kernel upgrades, and even surviving a power outage thanks to the Proxmox snapshot feature. Below I’ll spill the beans on how I built it, the backup routine I finally settled on, the annoyances that cropped up, and a handful of tips for anyone thinking of doing the same.
Hardware basics
My Proxmox box is nothing fancy – an Intel i7‑9700, 32 GB of DDR4 RAM, and a pair of 1 TB NVMe SSDs in a RAID‑1 configuration via ZFS. The VM that runs Vaultwarden only needs 2 vCPU cores and about 1 GB of RAM, but I give it 2 GB just to keep the OS and Docker comfortable. Disk space isn’t a concern either; the password database rarely exceeds a few megabytes, and even the attached file‑attachment cache stays well under 5 GB.
The software stack
I started with a clean Debian 11 “Bullseye” installation, then installed Docker Engine and Docker‑Compose. The docker‑compose.yml file is deliberately tiny – essentially a single service for Vaultwarden, a small Caddy container for automatic HTTPS (thanks to Let’s Encrypt), and a tiny cron job that runs a shell script to pull new images every week.
Why Caddy? I was tired of fiddling with Nginx config files, and Caddy’s auto‑TLS does the heavy lifting for me. It also plays nicely with Cloudflare’s proxy, so the SSL termination is double‑checked, which gives me a tiny bit of extra peace of mind.
Backup strategy – the part I spent the most time perfecting
At first I relied on Proxmox’s built‑in backup scheduler, taking a full VM snapshot every night. That seemed fine, but after a while I realized the snapshots ate up a lot of storage, and restoring a VM took longer than I wanted during a weekend power‑cut drill.
So I switched to a hybrid approach:
- Daily filesystem snapshots of the VM’s ZFS dataset using
zfs snapshot. Those are near‑instantaneous and only consume space for the delta. - Weekly tarball exports of the
/vw-datadirectory (which holds the SQLite DB and attachment files). I runrsyncto push the archive to an off‑site Synology NAS over SSH. - Monthly Docker image dumps – a simple
docker saveof the Vaultwarden image stored on an external USB drive. This is overkill for most, but it means I can rebuild the entire stack on a fresh host without pulling from the internet.
The script that ties this all together lives in /usr/local/bin/vw-backup.sh and is invoked by a systemd timer. It logs to /var/log/vw-backup.log, and I’ve set up a tiny logwatch rule to email me a summary every Monday.
Updates – the dance you have to learn
Every few weeks, a new Vaultwarden release pops up. My update workflow is intentionally manual: I SSH into the VM, run docker compose pull && docker compose up -d, then check the logs for any migration warnings. If everything looks good, I create a fresh ZFS snapshot before the next scheduled backup. This way, if an update breaks something (it happened once with a database schema change), I can roll back in a matter of minutes.
Automating updates entirely is tempting, but I’ve learned the hard way that a blind docker compose up -d after a weekend can leave you with a corrupted DB and an angry family trying to access their passwords.
Monitoring and alerts
I keep it simple: htop for a quick glance, and prometheus-node-exporter + Grafana on another VM to chart CPU, memory, and disk I/O. I also added a tiny health‑check endpoint to the Vaultwarden container and have Grafana send me a Slack message if the HTTP status isn’t 200 for more than five minutes.
These alerts have saved me from a few silent crashes, especially after a kernel panic that forced a reboot. The VM came back up, but the Vaultwarden service didn’t auto‑restart because Docker wasn’t set to restart on failure. Adding restart: unless-stopped to the compose file fixed that.
What didn’t work as expected
1. Proxmox backup retention – the default retention policy kept too many old snapshots, inflating storage usage. I tweaked the policy to keep only the last seven daily and four weekly snapshots.
2. Docker overlay networking – I initially tried to give the container a static IP on the host bridge, but it caused IP conflicts after a Proxmox network change. Switching to the default NAT bridge solved the issue.
3. Attachment size limits – By default Vaultwarden caps attachments at 10 MB. I increased it to 50 MB in the ADMIN_TOKEN environment, but forgot to also bump the Caddy client_max_body_size. After a couple of frustrated users, I added the missing directive.
Bottom line
If you already have a Proxmox host, throwing a small Debian VM into the mix for Vaultwarden is a low‑effort, high‑reward project. The key is to keep backups granular (ZFS snapshots + off‑site tarballs), to treat updates as a conscious step rather than an automatic cron, and to monitor the service just enough to catch the occasional hiccup.
Two years later, my family still trusts the vault with their passwords, and I’ve managed to keep the whole thing running on a single SSD without any major incidents. Give it a try – the learning curve is shallow, and the peace of mind is surprisingly tangible.
Editorial note: Nishadil may use AI assistance for news drafting and formatting. Readers can report issues from this page, and material corrections are reviewed under our editorial standards.