← Back to Wiki
Self-Hosting / Docker

Self-Host Vaultwarden (Bitwarden Server) on a Proxmox LXC

Vaultwarden is a lightweight, Bitwarden-compatible server. You get all the official Bitwarden apps and browser extensions, pointed at your own infrastructure instead of Bitwarden's cloud.

Here is how to run it properly, and how to migrate an existing instance without losing anything.

Share on X

Why isolate it

If you already run a pile of Docker containers on a NAS, it is tempting to add Vaultwarden as one more.

Do not. Your password vault then shares fate with everything else on that host. Container churn. Experiments. Reboots. It may also sit outside whatever backup job protects your real infrastructure.

Give it its own small VM or container, on its own backup schedule, isolated from everything else.

Basic deployment

services:
  vaultwarden:
    image: vaultwarden/server:latest
    restart: unless-stopped
    ports:
      - "80:80"
    volumes:
      - ./data:/data

That is most of it. Vaultwarden is a single lightweight binary and uses SQLite by default, so there is no external database to run.

Migrating an existing vault

Four things actually need to move.

BE WARNED: some NAS vendors ship a setuid-root rsync, and that breaks over SSH. Run rsync from a remote host over SSH against a NAS like this and it fails immediately with Permission denied, please try again. and a closed connection. The vendor's OS is correctly blocking a setuid-root binary from being called non-interactively. Use a tar stream over SSH instead.
ssh <nas> "sudo tar -C /path/to/vaultwarden -cf - --exclude=icon_cache --exclude=tmp ." \
  | tar -C <local-staging> -xf -

Cutover

Check whether your domain already goes through a reverse proxy that terminates TLS.

If it does, cutover is one edit. Point that rule's backend at the new address. No DNS change. No new certificate.

This works for any already reverse-proxied service. Check for the proxy before assuming a migration needs new TLS or DNS work.

Confirm the new instance is healthy before you flip it. Check the logs for a clean startup. Hit its health endpoint with GET /alive.

Then do a real login against the new backend. The migration is not done until that works.

Rollback safety net

Leave the old instance stopped, not deleted, and leave its data directory alone for a while.

It costs nothing and it is your rollback if something surfaces later that the migration missed.