Open-source synthetic monitoring and status pages, running on Cloudflare.
One click. Cloudflare clones this repo to your GitHub, provisions D1 / KV / Queue, and deploys the Worker.
Requires Workers Paid (~$5/month) for Durable Objects and Analytics Engine.
Create HTTP and heartbeat checks in the admin UI, run them from multiple Cloudflare regions, and publish a public page: fully operational / degraded / failing.
This is a GitHub template. Instance data (hosts, monitors, accounts) lives in your D1 after you deploy, never in this repo.
Foxwatch observes from Cloudflare. A global Cloudflare outage takes the observer down with the target. That is an explicit tradeoff, not a bug.
The Deploy to Cloudflare button:
- Clones this repo into your GitHub account
- Provisions D1
foxwatch-data, queuefoxwatch-alerts, and a KV namespace (name itfoxwatch-statuson the setup page) - Injects those IDs into your clone only, deploys the Worker, and turns on Workers Builds
Committed wrangler.jsonc in this template omits D1/KV IDs on purpose. Your account IDs never land in the public repo.
Then open /admin on your Worker and create the first superadmin (email + password).
This repo deploys from Actions on main. Nothing is written into wrangler.jsonc.
Create an API token: Cloudflare dashboard → Manage Account → API Tokens → Create Token → Custom token.
- Token name:
foxwatch-github-actions(or anything you like) - Account resources: Include → the account you will deploy to
- Zone resources: None
Account permissions
| Resource | Access |
|---|---|
| Workers Scripts | Write |
| Workers KV Storage | Write |
| D1 | Write |
| Queues | Write |
| Account Settings | Read |
Copy the token once. Put it in GitHub Settings → Secrets and variables → Actions.
Secret
| Name | Required |
|---|---|
CLOUDFLARE_API_TOKEN |
yes, the token above |
Variables (same page, Variables tab, or secrets with the same names)
| Name | Required |
|---|---|
CLOUDFLARE_ACCOUNT_ID |
yes, account ID |
FOXWATCH_D1_DATABASE_ID |
no, pin D1 foxwatch-data |
FOXWATCH_KV_NAMESPACE_ID |
no, pin KV foxwatch-status |
Without the ID variables, CI runs pnpm foxwatch init --yes (creates or reuses those named resources) then pnpm deploy. IDs are injected into the build output only.
A push with no Cloudflare credentials skips deploy so a fresh template clone stays green. Actions → CI → Run workflow fails instead of silently skipping.
Same setup works if you use this template instead of the button.
pnpm install
pnpm exec wrangler login
pnpm foxwatch init # D1 / KV / Queue → gitignored wrangler.cloud.jsonc
pnpm deployIf foxwatch-data or foxwatch-status already exists, init checks the D1 schema and asks before reusing. It will not migrate over unrelated tables. --yes skips the prompt (CI).
Needs Node 20+ and pnpm. No Cloudflare login.
pnpm install
pnpm dev- Public status: http://localhost:5173/
- Admin: http://localhost:5173/admin
A new instance has no checks and is named Foxwatch until you change it under Settings. Optional: copy .dev.vars.example to .dev.vars for ALLOW_HTTP_LOCAL=true or local header secrets.
All instance data is in D1: operator accounts, site name, HTTP and heartbeat checks, incidents.
Worker secrets for authenticated checks live on the Worker, not in git or D1. Register the name in admin, then:
pnpm exec wrangler secret put YOUR_SECRET_NAMESensitive headers must use a secret ref. Secrets attach only when the request host is in allowedHosts; cross-origin redirects strip them.
Heartbeats - create a check in admin, copy the token (or rotate it):
curl -X POST https://your-worker/api/heartbeat \
-H "Authorization: Bearer <token>"Tokens never go in URLs.
Status model
- Check: pass / degraded (latency SLO) / fail
- Component: operational / degraded / failing (region quorum, default majority)
- Banner: fully operational / degraded / failing (critical component down)
Public JSON, HTML, RSS, and badges do not include check URLs, headers, or error bodies.
apps/worker- Hono API, Durable Objects (Scheduler, Monitor, Probe)apps/web- admin UIpackages/config- check shape helperspackages/engine- URL policy, assertions, quorum, redactionmigrations- D1 schema
AGPL-3.0-or-later.