Skip to main content

Deployment and access

Production docs are static files served from a CDN. Authentication is enforced at the edge, not inside Docusaurus, so the site stays simple and cheap to scale.

Use Cloudflare Access as the identity proxy in front of Cloudflare Pages (or any static host behind Cloudflare).

Why this pattern

  • Scales with traffic: HTML and assets are cached at the edge; no per-request app auth server for reads.
  • Central policy: Enforce GitHub organization (or team) membership in one place.
  • Fits static Docusaurus: The doc build has no session layer; Access handles login before users reach the bucket.

Outline

  1. Deploy the built site to Cloudflare Pages (build output directory: build from apps/docs).
  2. Put the Pages hostname behind Cloudflare (if not already).
  3. In Zero Trust → Access → Applications, add an Self-hosted application for your docs hostname.
  4. Add an Identity provider for GitHub and require login.
  5. In the application policy, add a rule such as Include → Login method → GitHub and restrict further using:
    • Emails ending in @yourcompany.com, or
    • SAML/OIDC group claims if you connect an enterprise IdP, or
    • Access groups synced from GitHub teams / IdP groups (per your Cloudflare plan and IdP setup).

Exact UI labels change over time; in the Access application policy, express who is allowed as narrowly as your org needs (e.g. only members of a given GitHub organization by mapping identity via your IdP or email domain).

Build settings (Cloudflare Pages)

SettingValue
Root directoryapps/docs
Build commandbun install && bun run build
Build output directorybuild

Ensure the Pages project uses a Bun-compatible environment (install Bun in the build image or use a custom build command that installs Bun first if the default image does not include it).

Alternatives (from the architecture plan)

ApproachWhen to use
Vercel deployment protection / SSOAlready on Vercel; compare cost and IdP fit.
Application OAuth (e.g. Next.js middleware + GitHub API org check)Rich in-app RBAC for products like accounting; heavier than Access for plain docs.

For this documentation site, edge Access is the default recommendation.

Canonical URLs

SiteProduction hostname
Internal docs (this Docusaurus app)https://devdocs.keepintracks.com
Keepin' Tracks web (apps/tracks-web)https://personal.keepintracks.com

Set url in apps/docs/docusaurus.config.ts to match docs hostname. See ADR 0009.

Local deploy to Cloudflare (Wrangler)

Deploy from your machine after a successful local build—useful while GitHub Actions usage on develop is reduced (ADR 0008).

One-time setup

  1. Install dependencies at the repo root: bun install.
  2. Authenticate Wrangler: bunx wrangler login (opens a browser).
  3. Account ID: root deploy scripts set CLOUDFLARE_ACCOUNT_ID for the org’s account; apps/tracks-api/wrangler.jsonc includes the same account_id for Worker deploys. Override with export CLOUDFLARE_ACCOUNT_ID=… if you use a different account.
  4. Create Pages projects the first time (only if they do not exist):
    CLOUDFLARE_ACCOUNT_ID=<id> bunx wrangler pages project create keepin-devdocs and the same for keepin-personal (or pick other project names and update package.json deploy scripts). After the first deploy, each project has a *.pages.dev preview URL; map custom domains in the dashboard: devdocs.keepintracks.comkeepin-devdocs, personal.keepintracks.comkeepin-personal (DNS + TLS in the keepintracks.com zone).
  5. Worker tracks-api is created on first bun run deploy:tracks-api; it receives a workers.dev URL (e.g. https://tracks-api.<subdomain>.workers.dev) until you add a custom route.

Commands (from repository root)

Example Pages project names are keepin-devdocs and keepin-personal—create projects with these names or pass your own --project-name / Worker name.

TargetBuildDeploy
Docs sitebun run docs:buildbun run deploy:docs
Tracks webbun run tracks-web:buildbun run deploy:tracks-web
Tracks API (Worker)(uses Worker bundle)bun run deploy:tracks-api

The root package.json scripts wrap wrangler pages deploy and wrangler deploy so the CLI version stays pinned with the monorepo.

Workers API routing

The Keepin' Tracks API runs as a Cloudflare Worker (apps/tracks-api). Map a hostname or route under your zone (e.g. api.personal.keepintracks.com or path-based routing) in the Workers & Pages dashboard so the browser can call the API from personal.keepintracks.com with CORS already allowing that origin in code.

Build settings reference (Cloudflare Pages, CI alternative)

If you later reconnect Git-driven Pages builds, mirror:

ProjectRoot directoryBuild commandOutput
Docsapps/docsbun install && bun run buildbuild
Tracks webapps/tracks-webbun install && bun run builddist