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.
Recommended: Cloudflare Access + GitHub
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
- Deploy the built site to Cloudflare Pages (build output directory:
buildfromapps/docs). - Put the Pages hostname behind Cloudflare (if not already).
- In Zero Trust → Access → Applications, add an Self-hosted application for your docs hostname.
- Add an Identity provider for GitHub and require login.
- 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)
| Setting | Value |
|---|---|
| Root directory | apps/docs |
| Build command | bun install && bun run build |
| Build output directory | build |
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)
| Approach | When to use |
|---|---|
| Vercel deployment protection / SSO | Already 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
| Site | Production 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
- Install dependencies at the repo root:
bun install. - Authenticate Wrangler:
bunx wrangler login(opens a browser). - Account ID: root deploy scripts set
CLOUDFLARE_ACCOUNT_IDfor the org’s account;apps/tracks-api/wrangler.jsoncincludes the sameaccount_idfor Worker deploys. Override withexport CLOUDFLARE_ACCOUNT_ID=…if you use a different account. - Create Pages projects the first time (only if they do not exist):
CLOUDFLARE_ACCOUNT_ID=<id> bunx wrangler pages project create keepin-devdocsand the same forkeepin-personal(or pick other project names and updatepackage.jsondeploy scripts). After the first deploy, each project has a*.pages.devpreview URL; map custom domains in the dashboard: devdocs.keepintracks.com →keepin-devdocs, personal.keepintracks.com →keepin-personal(DNS + TLS in thekeepintracks.comzone). - Worker
tracks-apiis created on firstbun 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.
| Target | Build | Deploy |
|---|---|---|
| Docs site | bun run docs:build | bun run deploy:docs |
| Tracks web | bun run tracks-web:build | bun 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:
| Project | Root directory | Build command | Output |
|---|---|---|---|
| Docs | apps/docs | bun install && bun run build | build |
| Tracks web | apps/tracks-web | bun install && bun run build | dist |