The Cloudflare target runs Checky as a Worker with a D1 database, two Durable Objects (live updates per organization and rate limiting), a Cron Trigger every minute and the web app as static assets. It is the same code that runs the hosted service, in single-organization mode.
We recommend the Workers Paid plan: it gives sign-in password hashing enough CPU time and raises D1’s per-request limits (relevant when importing a large organization). The bundle also fits the free plan.
One-click deploy
- Click the Deploy to Cloudflare button in the repository’s
apps/worker/README.md(or on your account page after purchase). - Cloudflare forks the code into your GitHub account, creates the D1 database and the Durable Objects and
asks for two secrets. Generate each with
openssl rand -base64 48:BETTER_AUTH_SECRET— signs sessions.APP_SECRET— signs one-tap email links and reply addresses, encrypts SSO secrets.
- Workers Builds builds the web app, deploys the Worker and applies the D1 migrations.
After the first deploy
- Open
https://checky.<your-subdomain>.workers.devand complete the first-run setup (owner account and organization), or choose “Moving from another Checky?” to restore an export. - Optional: add a custom domain (Worker → Settings → Domains & Routes), then set the variable
BASE_URLto the finalhttps://URL (Settings → Variables). Passkeys and OAuth callbacks are bound to this host. - Set up email (below), and optionally
CHECKY_LICENSE_KEYand social sign-in secrets (see Configuration).
Email on Cloudflare
Sending uses the Worker’s send_email binding:
- Dashboard → your domain → Email → Email Routing: enable it (adds MX and SPF records).
- Email Sending: verify the sender domain or address you put into
EMAIL_FROM(DKIM records are added for you). Without Email Sending the binding can only deliver to verified destination addresses — enough for a test, not for your team. EMAIL_TRANSPORT=cloudflareis the default when the binding exists (consoleonly logs, for debugging).
Replies (answer a check-in by replying to the email):
- Pick a subdomain, e.g.
reply.example.com, and enable Email Routing for it. - Routing rules → Catch-all (or the custom address
reply+*) → action Send to a Worker → your Checky Worker. - Set
EMAIL_REPLY_DOMAIN=reply.example.com. Test by replying “yes” to a reminder.
SMTP cannot be used from Workers. If you need SMTP, run Docker.
Updates
Sync your fork with the new release tag; Workers Builds deploys the next push automatically (Worker plus D1 migrations). From a local checkout:
git pull
pnpm install
pnpm --filter @checky/worker run deploy # wrangler deploy + wrangler d1 migrations apply DB --remote
Roll back code with wrangler rollback, data with D1 Time Travel (wrangler d1 time-travel restore), see
Backups and upgrades.
Try it locally (no Cloudflare account)
cp apps/worker/.dev.vars.example apps/worker/.dev.vars # replace the example secrets
pnpm --filter @checky/worker dev # http://localhost:8787, local D1
curl "http://localhost:8787/__scheduled?cron=*+*+*+*+*" # run one scheduler tick
Limits
- The Deploy button needs the code in a public repository (or a public copy of it).
- Importing a very large organization on the free plan can exceed D1’s per-request limits — use the paid plan.