Deployment

Health Observability is deployed as a Cloudflare Worker with static assets using Wrangler. The database is Cloudflare D1. No other infrastructure is required.

Prerequisites

  • Cloudflare account with Workers and D1 enabled
  • Node.js 18+
  • wrangler CLI (included as a dev dependency)
npm install          # installs wrangler
npx wrangler login   # authenticate with Cloudflare

Repository Structure for Deployment

health-observability/
├── worker/index.js        # Worker entry point (main = "worker/index.js")
├── frontend/              # Static assets (HTML, JS, CSS)
│   ├── index.html
│   ├── app.js
│   └── style.css
├── migrations/            # D1 SQL migrations (applied in order)
└── wrangler.toml          # Wrangler configuration

wrangler.toml Reference

name               = "health-observability"
main               = "worker/index.js"
compatibility_date = "2026-03-15"

d1_databases = [
  {
    binding       = "DB",
    database_name = "health_observability",
    database_id   = "9c5c7df0-aea8-4092-bc9b-a7a7de420c3f"
  }
]

[vars]
APP_ENV = "production"

[assets]
directory        = "./frontend"
binding          = "ASSETS"
run_worker_first = true

Key Settings

SettingValuePurpose
mainworker/index.jsWorker entry point
compatibility_date2026-03-15Locks Web API behaviour
d1_databases[].bindingDBAvailable in Worker as env.DB
assets.directory./frontendStatic files to upload
assets.run_worker_firsttrueAPI routes take priority over static assets

Deployment Flow

flowchart TD Dev["Developer workstation"] Wrangler["npx wrangler deploy"] Upload["Wrangler uploads:\n- worker/index.js\n- frontend/* (as assets)"] CF["Cloudflare edge network"] D1[("D1 database\n(pre-existing)")] Dev --> Wrangler Wrangler --> Upload Upload --> CF CF --> D1

Database Setup

1. Create the D1 Database

npx wrangler d1 create health_observability

Copy the generated database_id into wrangler.toml.

2. Apply Migrations

Migrations are applied in numbered order. Wrangler tracks which migrations have been applied.

npx wrangler d1 migrations apply health_observability

This applies all files in migrations/ that have not yet been run, in lexicographic order:

migrations/01_create_metric_types.sql
migrations/02_create_measurement_sessions.sql
migrations/03_create_observations.sql
migrations/04_create_tags.sql
migrations/05_create_session_tags.sql
migrations/06_add_indexes.sql
migrations/07_add_profile_and_weight.sql
migrations/08_add_cpap_data.sql

3. Seed Metric Types

After applying migrations, seed the metric_types table:

INSERT INTO metric_types (name, unit, category, description) VALUES
  ('systolic',             'mmHg', 'blood_pressure', 'Systolic blood pressure'),
  ('diastolic',            'mmHg', 'blood_pressure', 'Diastolic blood pressure'),
  ('pulse',                'bpm',  'blood_pressure', 'Heart rate / pulse'),
  ('pulse_pressure',       'mmHg', 'blood_pressure', 'Pulse pressure (sys - dia)'),
  ('mean_arterial_pressure','mmHg','blood_pressure', 'Mean arterial pressure');

Run via:

npx wrangler d1 execute health_observability --command "INSERT INTO metric_types ..."

Or save to a file and run:

npx wrangler d1 execute health_observability --file ./seed.sql

Deploy

npx wrangler deploy

Wrangler bundles the Worker, uploads static assets to Cloudflare’s asset store, and publishes the Worker to the edge. The Worker URL is printed on completion.

Environment Variables

VariableValueAccess
APP_ENV"production"env.APP_ENV in Worker

Database credentials are not stored as environment variables — D1 access is managed via the d1_databases binding in wrangler.toml.

Local Development

Run a local dev server with live reloading:

npx wrangler dev

This starts a local Worker proxy at http://localhost:8787. D1 reads/writes go to a local SQLite file by default.

To use the remote D1 database locally:

npx wrangler dev --remote

Updating the Frontend

The frontend is plain HTML/JS/CSS — no build step required. After editing files in frontend/, re-deploy:

npx wrangler deploy

Adding a New Migration

  1. Create a new numbered file in migrations/:
    migrations/09_my_change.sql
    
  2. Write the SQL
  3. Apply to the remote database:
    npx wrangler d1 migrations apply health_observability
    

Wrangler will apply only the new migration, leaving existing data intact.

Architecture at Deploy Time

sequenceDiagram participant Dev as Developer participant W as Wrangler CLI participant CF as Cloudflare participant Edge as Edge Workers Dev->>W: npx wrangler deploy W->>W: Bundle worker/index.js (ESM) W->>CF: Upload Worker bundle W->>CF: Upload frontend/* as asset bundle CF->>Edge: Distribute Worker to all PoPs CF->>Edge: Distribute asset bundle (CDN) Edge-->>Dev: Deployment URL

Monitoring

Cloudflare provides:

  • Workers Analytics — request counts, CPU time, error rates
  • D1 Analytics — query counts and storage usage
  • Real-time logs via npx wrangler tail
npx wrangler tail   # stream live Worker logs

Cost

Under Cloudflare’s free tier (as of 2026):

  • Workers: 100,000 requests/day free
  • D1: 5 million rows read / 100,000 rows written per day free
  • Assets: Served via Cloudflare CDN free

A personal health tracker generates negligible traffic, making this effectively free to operate.