English | 中文
Deploy Uptimer to Cloudflare using the built-in GitHub Actions workflow.
- A GitHub repository (default branch:
masterormain) - A Cloudflare account
- A Cloudflare API Token with deployment permissions
- Access to repository Settings > Secrets and Variables
Trigger: Push to main/master, or manual workflow_dispatch
File: .github/workflows/deploy.yml
Steps (in order):
- Install Node + pnpm + dependencies
- Resolve Cloudflare Account ID (reads from config, falls back to API query)
- Compute resource names (Worker / Pages / D1)
- Check or create D1 database, inject real
database_idinto tempwrangler.ci.toml - Run remote D1 migrations
- Deploy Worker
- (Optional) Write Worker Secret:
ADMIN_TOKEN - Build and deploy Pages
- (Optional) Write Pages Secret:
UPTIMER_API_ORIGIN
| Name | Required | Description |
|---|---|---|
CLOUDFLARE_API_TOKEN |
Yes | Cloudflare API authentication |
UPTIMER_ADMIN_TOKEN |
Yes | Admin dashboard access key; auto-injected as Worker ADMIN_TOKEN secret |
| Name | Description |
|---|---|
CLOUDFLARE_ACCOUNT_ID |
Avoids auto-resolution failures |
Override default naming and routing:
| Name | Default | Description |
|---|---|---|
UPTIMER_PREFIX |
Repository name slug | Unified resource name prefix |
UPTIMER_WORKER_NAME |
${UPTIMER_PREFIX} |
Worker name |
UPTIMER_PAGES_PROJECT |
${UPTIMER_PREFIX} |
Pages project name |
UPTIMER_D1_NAME |
${UPTIMER_PREFIX} |
D1 database name |
UPTIMER_D1_BINDING |
DB |
D1 binding name in Worker |
UPTIMER_API_BASE |
Auto-derived or /api/v1 |
API address (e.g. https://my-worker.example.com/api/v1 or /api/v1) |
UPTIMER_API_ORIGIN |
Auto-derived | API origin (e.g. https://my-worker.example.com); /api/v1 appended automatically |
VITE_ADMIN_PATH / UPTIMER_ADMIN_PATH |
— | Custom admin dashboard path |
If no naming variables are set, the workflow uses the repository name slug as the default prefix. This keeps names stable across forks.
API address: Usually no configuration needed — the workflow detects the Worker URL automatically. Set
UPTIMER_API_BASEorUPTIMER_API_ORIGINonly if the API is on a custom domain. Both accept the same information in different formats; setting one is enough.
The workflow creates and updates multiple resources. Your token needs:
- Workers Scripts: deploy and manage secrets
- D1: query, create, and migrate databases
- Pages: create projects and deploy
- Account: read account info (for account ID resolution)
- Add
CLOUDFLARE_API_TOKENto repository secrets - Add
UPTIMER_ADMIN_TOKEN(admin dashboard access key) - Add
CLOUDFLARE_ACCOUNT_ID(recommended) - (Optional) Set
UPTIMER_PREFIXto avoid name collisions - Push to
master/main, or manually trigger "Deploy to Cloudflare" - Once the workflow succeeds, note the Worker URL and Pages URL from the logs
- Visit the Pages URL (public status page)
- Navigate to
/admin(or your customVITE_ADMIN_PATH)
# Public API
curl https://<worker-url>/api/v1/public/status
# Admin API
curl https://<worker-url>/api/v1/admin/monitors \
-H "Authorization: Bearer <YOUR_ADMIN_TOKEN>"Use Wrangler to check that key tables exist in D1:
monitors, monitor_state, check_results, outages, settings
- Verify
CLOUDFLARE_API_TOKENis set and valid - Confirm the token has account read permissions
- Set
CLOUDFLARE_ACCOUNT_IDexplicitly to skip auto-resolution
- Check that
UPTIMER_D1_BINDINGmatches the binding inapps/worker/wrangler.toml - Verify migration SQL is idempotent and syntactically correct
- Verify that
UPTIMER_API_BASEorUPTIMER_API_ORIGINpoints to your Worker, not to the Pages site - "API returned HTML instead of JSON" usually means the URL is hitting Pages (which returns HTML) instead of the Worker
- If neither variable is set, the workflow uses the Worker URL automatically — check that it resolved correctly in the deploy logs
- Confirm
UPTIMER_ADMIN_TOKENwas written to the Worker Secret - Check that the token in the browser's localStorage matches the secret
Prefer redeploying the last known-good commit:
- Find the last green deployment commit
- Re-trigger "Deploy to Cloudflare" from that commit
- If schema changes are involved, add a new forward-compatible migration rather than rolling back
D1 migrations should not be rolled back destructively. If a remote migration was already applied, fix forward with a new migration.
| Workflow | Purpose |
|---|---|
ci.yml |
Quality gate: lint, typecheck, test |
deploy.yml |
Production release |
Recommended branch strategy:
- PRs must pass CI before merging
master/mainonly receives reviewed changes- Releases are triggered automatically on push — no manual drift