Trusting a cloud password manager is fine until you need to trust it completely. I run my own stack—Proxmox, Docker, Ansible—so hosting Vaultwarden at home is not a hobby, it is infrastructure. A new guide from LocalToNet walks through the standard Docker install, but the devil is in the details they almost get right.
What the guide covers
The LocalToNet post, dated March 5, 2026, lays out the usual four-step dance: install Docker, generate an ADMIN_TOKEN hashed with Argon2id, create a project directory with a .env file, and spin up a docker-compose.yml. It is standard stuff. For someone who has never run docker compose up, it is a clean on-ramp. The container image is vaultwarden/server:latest, the port mapping is 80:80, and the volume is named vw-data. It will get you a login screen. It will not get you a production setup.
That last part is where I stop nodding.
Hash the admin token properly
The guide correctly tells you to hash the ADMIN_TOKEN with Argon2id. Most guides skip this and let people paste plaintext into an env var. Do not do that. Vaultwarden accepts an Argon2id hash starting with $argon2id$ and verifies against it at runtime. This means the container never holds your raw token in memory as a plaintext string, which matters if someone dumps the process environment.
I generate mine with the argon2 binary:
echo -n 'your-secret-token' | argon2 $(openssl rand -hex 16) -e -id -k 65540 -t 3 -p 4
Paste the resulting hash into your .env file. If you do not have argon2 installed locally, the Vaultwarden container itself can generate it, but running crypto inside a shell pipeline makes me nervous. I prefer the host binary. Rotate this token yearly. Automate it if you can.
Stop using anonymous named volumes
The guide uses vw-data:/data. That creates a named Docker volume you cannot easily inspect from the host without jumping through docker volume inspect hoops. I bind mount a host directory every time.
volumes:
- /opt/vaultwarden/data:/data
I back that directory with restic to my TrueNAS box nightly. If the container dies, the data is a directory on the host. If I need to migrate the LXC to another Proxmox node, I rsync one path. Simple.
TLS is not optional
The guide mentions reverse proxy in passing. I will be blunt: running Vaultwarden over HTTP on your LAN and calling it safe because your WiFi is password-protected is malpractice. I terminate TLS at my Caddy instance on the Proxmox host, which handles ACME DNS challenges against my internal DNS.
# Caddyfile snippet
vaultwarden.lab.mydomain.com {
reverse_proxy vaultwarden:80
}
The Vaultwarden container itself listens on plain HTTP inside a Docker network that only Caddy can reach. I do not expose port 80 on the host at all. No admin panel reachable without WireGuard. If you are not doing this, fix it before you store a single password.
Backup strategy: SQLite is a file
Vaultwarden defaults to SQLite. The guide does not mention backups. That is a glaring omission. SQLite is great because you can copy the file if the container is stopped, or use sqlite3 .backup if it is running. I run a systemd timer inside the LXC that does:
sqlite3 /opt/vaultwarden/data/db.sqlite3 ".backup '/backup/vaultwarden/db-backup.sqlite3'"
Then restic picks it up. If you want Postgres, Vaultwarden supports it, but for a home lab with five family accounts, SQLite plus a real backup job is lighter and faster.
What I am doing next
I already run Vaultwarden in a Debian 12 LXC on the Proxmox cluster. After reading this guide, I am adding an Ansible task to my docker-compose role that generates a fresh Argon2id hash and updates the .env file only when the token age exceeds ninety days. I am also migrating from the named vw-data volume to a bind mount at /opt/vaultwarden/data so restic can see it without Docker indirection. Postgres is not on the roadmap. SQLite plus a nightly sqlite3 .backup is sufficient. The admin panel stays off the public internet. It will stay behind WireGuard, where it belongs.