-
Notifications
You must be signed in to change notification settings - Fork 0
deployment
How the travel SPA gets to production at https://travel.mestumre.dev.
The SPA is a Vite-built static bundle served from Cloudflare
Pages. It talks to the NoETL gateway on a separate origin
(https://gateway.mestumre.dev). The gateway and the NoETL
server run on GKE.
| Surface | Hosting | Source |
|---|---|---|
| SPA static bundle | Cloudflare Pages |
dist/ (Vite build output) |
| Container image (alt. for self-host) | Docker / OCI |
Dockerfile + nginx.conf
|
| Cloudflare Workers / Pages config | Cloudflare | wrangler.toml |
| Build script | Local / CI | scripts/build_container.sh |
The SPA build runs Vite with TypeScript and produces a static bundle:
npm ci
npm run contracts # regenerate src/contracts/widgets.ts from JSON schemas
npm run type-check # tsc --noEmit
npm run build # tsc --noEmit && vite buildThe output lands in dist/. The package's build:cf script
runs the full sequence in one command for Cloudflare Pages.
The SPA reads these VITE_* env vars at build time. The full
list is in
.env.example.
| Var | What |
|---|---|
VITE_NOETL_API_BASE_URL |
Direct NoETL API base, used only in guest mode (local dev). |
VITE_GATEWAY_BASE_URL |
Production gateway URL (e.g. https://gateway.mestumre.dev). |
VITE_ALLOW_GUEST |
true to bypass auth in local dev. Production builds set this false. |
VITE_AUTH0_DOMAIN |
Auth0 tenant (e.g. mestumre-development.us.auth0.com). |
VITE_AUTH0_CLIENT_ID |
Auth0 SPA client ID (public value). |
VITE_GOOGLE_MAPS_KEY |
Restricted Google Maps embed key. |
None of these are secrets. The Auth0 domain and client ID are public; the Google Maps key is restricted by referrer; the gateway URL is intentionally a public endpoint.
The travel SPA is deployed via Wrangler:
npm run deploy:cf
# expands to: npx wrangler pages deploy dist --project-name travel --branch mainWrangler picks up wrangler.toml. The main branch is the
production deployment; other branches map to preview URLs.
Cloudflare Pages sits behind Cloudflare DNS for
travel.mestumre.dev. Access protection (Cloudflare Access)
can be added in front; the gateway-session model works equally
well with or without it.
For self-hosting or container-based platforms, the SPA also builds as a Docker image with nginx serving the bundle:
TAG="$(date -u +%Y%m%d-%H%M%S)" ./scripts/build_container.shThe build script:
- Runs
npm ci && npm run buildinside a build stage. - Copies
dist/into an nginx-alpine image. - Tags the result with the date-stamp.
The container exposes nginx on port 80; nginx.conf declares
the SPA's history-API fallback so /route/anything falls back
to /index.html.
The SPA's backend is on a separate cluster:
-
Gateway: GKE deployment in the
gatewaynamespace, fronted by a Cloudflare Tunnel (cloudflare/noetl-gke-gateway-tunnel). -
NoETL server + worker pool: GKE deployment in the
noetlnamespace, exposed only inside the cluster. -
NATS: GKE deployment in the
natsnamespace. -
Postgres: Cloud SQL with PgBouncer in the
postgresnamespace.
For the deploy mechanism on the backend side, see the GKE Helm install page on the ops wiki.
The production setup:
-
travel.mestumre.dev→ Cloudflare Pages (SPA). -
gateway.mestumre.dev→ Cloudflare Tunnel → GKE gateway service. - Auth0 application:
Allowed Callback URLs,Allowed Logout URLs,Allowed Web Origins, andAllowed Origins (CORS)all includehttps://travel.mestumre.dev. - Auth0 application's
application_typeisSingle Page Application(no client secret used in the browser flow; the gateway has the client secret server-side).
When forking, replace mestumre.dev everywhere with your
domain and update the Auth0 application URLs to match.
cp .env.example .env.local
# edit .env.local with your local NoETL / gateway URLs
npm install
npm run devSet VITE_ALLOW_GUEST=true in .env.local to skip Auth0
during local iteration. The SPA will hit a local NoETL at the
VITE_NOETL_API_BASE_URL you configured.
For a quick local NoETL, follow the kind install path.
Required checks (all passing in CI):
npm test # vitest unit suite
npm run smoke:widgets # widget envelope round-trip harness
npm run type-check # tsc --noEmit
npm run lint # tsc --noEmit (same; redundant alias)
npm run build # full buildThe CI workflow under
.github/workflows/
gates merges on these.
- Architecture — what's running where.
- Auth and session — Auth0 + gateway session.
- GKE Helm install — the backend cluster.
- In-repo:
docs/deployment/travel-subdomain.md— Cloudflare Pages setup runbook.
Travel SPA
Architecture
- Architecture
- Widget contract
- Business data via playbooks
- Playbook: itinerary-planner
- Playbook: calendar/list
Integration
Operations
See also
- noetl wiki (app)
- ops wiki (deploy)
- Ephemeral Blueprints