Run Vaultwarden (Bitwarden-compatible server) on Cloudflare Workers using Containers. A minimal Worker forwards HTTP and WebSocket traffic to a managed container; data lives in an external database.
- Minimal Worker in TypeScript routes:
/notifications/hub→ container port 3012 (WebSocket)- everything else → container port 80 (HTTP)
wrangler.jsoncpreconfigured for Containers, Durable Object binding, and logs.Dockerfileusesvaultwarden/server:latestas the base image.
- Workers + Durable Objects (Containers)
- Managed Container Registry (built/pushed by Wrangler)
- Observability (logs)
- Runtime:
@cloudflare/containers - Dev:
wrangler,typescript,prettier
- Cloudflare account and Wrangler CLI
- Docker Desktop (for local build/run)
- Publicly reachable database
- Recommended: Neon (free Postgres)
- MySQL also works if hosted publicly; local DBs behind Cloudflare Tunnel won’t work from deployed Workers/Containers
- Configure domain in
wrangler.jsonc
- Set
vars.DOMAINto your URL (e.g.,https://vault.example.com) - Use
workers_dev: truefor*.workers.dev, or setroutesfor your domain
- Create a database (Neon)
- Create a project at https://neon.tech and copy the connection string
- Use
postgresql://USER:PASSWORD@HOST/DB?sslmode=require
- Set secrets
wrangler secret put DATABASE_URL
wrangler secret put ADMIN_TOKEN # optional (plaintext works; PHC hash preferred)- Deploy
npx wrangler deployOpen your route or *.workers.dev URL.
- Option A: temporarily enable signups
- Set
SIGNUPS_ALLOWEDto"true"inwrangler.jsonc, deploy, sign up, then set back to"false"and redeploy.
- Set
- Option B: admin page & invites (needs SMTP)
- Set
ADMIN_TOKEN, deploy, visit/adminto invite users
- Set
- In the Web Vault: Tools → Import Data → Bitwarden (json)
- Note: attachments are not included in Bitwarden exports
- Image updates:
latestis resolved at build time. Re-deploy to pick up new Vaultwarden releases. For reproducibility, pin to a tag or digest. - Tooling updates: run
npm outdated/npm updateto bumpwrangler,typescript,@cloudflare/containers.
- 500 or “not listening on 10.0.0.1:80”: usually database connectivity — use a hosted DB. For local dev, use
host.docker.internal. - Cloudflare Tunnel for TCP won’t help from Workers/Containers; they can’t run a
cloudflaredclient. - Docker on Apple Silicon: first amd64 build is slow; ensure you have disk space.
- Types: prefer
wrangler types; avoid adding Node types totsconfig.
- Vaultwarden: https://github.com/dani-garcia/vaultwarden
- Cloudflare Containers: https://developers.cloudflare.com/containers/
- Durable Objects Container class: https://developers.cloudflare.com/durable-objects/api/container/
- Workers Node.js compatibility: https://developers.cloudflare.com/workers/runtime-apis/nodejs/
- Neon (Postgres): https://neon.tech
- Consider protecting your public route with Cloudflare Access (SSO/MFA).
- Prefer an Argon2 PHC
ADMIN_TOKENover plaintext when possible (optional).
- Admin panel is disabled even when setting ADMIN_TOKEN
- Started getting "An error has occurred. Container suddenly disconnected, try again" error after a week of non usage, redeploying did not fix it. Trying again from scratch.
- Some clients drop the connection and log out of the account entirely when the container sleeps.
Add a LICENSE and CONTRIBUTING.md to suit your needs. PRs welcome!