Skip to content

adam0white/vaultwarden-cf

Repository files navigation

Vaultwarden on Cloudflare Containers

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.

What this is

  • Minimal Worker in TypeScript routes:
    • /notifications/hub → container port 3012 (WebSocket)
    • everything else → container port 80 (HTTP)
  • wrangler.jsonc preconfigured for Containers, Durable Object binding, and logs.
  • Dockerfile uses vaultwarden/server:latest as the base image.

Cloudflare resources used

  • Workers + Durable Objects (Containers)
  • Managed Container Registry (built/pushed by Wrangler)
  • Observability (logs)

Dependencies

  • Runtime: @cloudflare/containers
  • Dev: wrangler, typescript, prettier

Requirements

  • 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

Quick start

  1. Configure domain in wrangler.jsonc
  • Set vars.DOMAIN to your URL (e.g., https://vault.example.com)
  • Use workers_dev: true for *.workers.dev, or set routes for your domain
  1. Create a database (Neon)
  • Create a project at https://neon.tech and copy the connection string
  • Use postgresql://USER:PASSWORD@HOST/DB?sslmode=require
  1. Set secrets
wrangler secret put DATABASE_URL
wrangler secret put ADMIN_TOKEN   # optional (plaintext works; PHC hash preferred)
  1. Deploy
npx wrangler deploy

Open your route or *.workers.dev URL.

Create your first user

  • Option A: temporarily enable signups
    • Set SIGNUPS_ALLOWED to "true" in wrangler.jsonc, deploy, sign up, then set back to "false" and redeploy.
  • Option B: admin page & invites (needs SMTP)
    • Set ADMIN_TOKEN, deploy, visit /admin to invite users

Import from Bitwarden

  • In the Web Vault: Tools → Import Data → Bitwarden (json)
  • Note: attachments are not included in Bitwarden exports

Maintenance

  • Image updates: latest is 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 update to bump wrangler, typescript, @cloudflare/containers.

Troubleshooting

  • 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 cloudflared client.
  • Docker on Apple Silicon: first amd64 build is slow; ensure you have disk space.
  • Types: prefer wrangler types; avoid adding Node types to tsconfig.

Links

Security notes

  • Consider protecting your public route with Cloudflare Access (SSO/MFA).
  • Prefer an Argon2 PHC ADMIN_TOKEN over plaintext when possible (optional).

Known issues

  • 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.

License / Contributing

Add a LICENSE and CONTRIBUTING.md to suit your needs. PRs welcome!

About

Run Vaultwarden (Bitwarden-compatible password manager) on Cloudflare Workers using Containers. TypeScript Worker routes WebSocket traffic to port 3012 and HTTP requests to port 80. Uses Durable Objects with external database (Neon Postgres recommended). Supports intelligent request routing and persistent storage.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors