Skip to content
Browse the docs

Self-hosting

Run Crunu on Cloudflare Workers

Deploy the Crunu server as a Cloudflare Worker with a D1 database, choose the right Workers plan for a team, and turn off compression for API responses.

Last updated

On this page

On Cloudflare, the Crunu server runs as a Worker and keeps its data in D1. There is no server of your own to maintain. Read Self-hosting: overview and platforms first and prepare .env.

What you need

  • wrangler, installed with npm install -g wrangler, and a completed wrangler login;
  • the web app of the same version in dist/web/, as described in Docker;
  • a domain on Cloudflare for the server address.

Deploy

Shell
sh deploy/cloudflare/deploy.sh --name vault-company --location weur

The script builds the Worker, creates the D1 database vault-company-db if it doesn't exist, and deploys the Worker together with its secrets as one version. Code and keys change at the same moment. If the deploy fails, nothing on the Worker changes.

Attach your domain to the Worker in the Cloudflare dashboard under Workers & Pages, your Worker, Settings, Domains & Routes, and use the same address in PUBLIC_ORIGIN.

Secrets that are no longer in .env, for example SERVER_KEY_PREVIOUS after a key rotation, are listed by the script. Add --prune to remove them in one request.

To build and inspect what would go to the Worker without deploying, add --build-only. The script builds the Worker and its wrangler.toml, prints the build fingerprint and the names of the secrets that would be sent, and stops. The D1 database must already exist in this mode. The build is reproducible, so running the same command without --build-only deploys exactly what you inspected.

Which Workers plan

The free Workers plan is enough to try Crunu. A team should use Workers Paid. The Crunu deploy guide was written against Cloudflare's published limits, under which a request on the free plan gets only 10 ms of CPU time and one Worker call can make only 50 D1 queries. Check Cloudflare's current limits and pricing before you choose.

  • Heavy requests. A sign-in, a key rotation or a large environment can hit the 10 ms CPU limit on the free plan and fail.
  • Cleanup. One cleanup pass makes more than 50 D1 queries even with a single organization, so on the free plan it stops before the network-rules module. Network alerts are then not reconciled or closed, and the network denial records aren't trimmed. The network rules themselves still work correctly, because their timing is checked on every request.

Compression of API responses

The Worker answers /v2/* with Content-Encoding: identity and Cache-Control: no-store, no-transform, because the size of a response carrying tokens and ciphertext shouldn't reveal anything. Cloudflare's documentation doesn't say whether its edge compresses such responses, so check your live address:

Shell
node scripts/doctor.mjs https://vault.company.example

If the API compression check shows compression, add a Compression Rule to the server's zone with the action to disable compression for paths that start with /v2/:

Text
starts_with(http.request.uri.path, "/v2/")

Then run doctor again. This works only on your own domain, because *.workers.dev has no zone of its own.

Old versions and preview URLs

Every uploaded Worker version can have its own preview address on workers.dev. Old versions run with the same database and the same secrets, so a fix in a new version doesn't apply to requests sent to an old one. The Crunu wrangler.toml template turns preview URLs off, and each deploy turns them off for the whole Worker, old versions included. If wrangler suggests turning preview_urls on, don't.

Client addresses and network rules

On Workers, the platform provides the client address, so there is no TRUST_PROXY to set. If you use network rules with IPv6 networks, keep Cloudflare's Pseudo IPv4 setting off or in Add header mode. In Overwrite headers mode, Cloudflare replaces IPv6 client addresses with addresses from 240.0.0.0/4, and rules with IPv6 networks no longer match those clients.

Cleanup, logs and rollback

  • Cleanup runs every 5 minutes from a cron trigger.
  • Logs: wrangler tail --config dist/server/cloudflare/wrangler.toml, or the Worker's Logs in the dashboard.
  • Rollback: in the dashboard, open the Worker's Deployments, pick the previous version and choose Rollback, or run wrangler rollback. Migrations only add, so the previous version works with the current database.
  • Backups: turn on D1's own point-in-time restore, Time Travel, as an extra layer. Its window depends on your plan. Keep exporting Crunu archives as well, because they move between platforms and can be verified. See Backups and restore.

While Cloudflare exports a D1 database, it doesn't answer the server's queries. That usually takes seconds.