Docs Site — Cloudflare Pages + Access setup¶
Publishes
docs/eop-tasks/anddocs/Task Log.mdas a private, mobile-friendly static site athttps://tasks.theestablishers.com/(or whichever subdomain you pick). Built by MkDocs Material, hosted by Cloudflare Pages, gated by Cloudflare Access. Cost: $0 — stays inside the Cloudflare Free + Zero Trust Free tiers.The build code (
mkdocs.yml,scripts/build-docs-site.py,requirements-docs.txt) is already merged. This runbook is the Cloudflare-dashboard side: one project to create, one Access application to gate it.
What you get¶
- One landing page (Task Board) showing all 70+ tasks grouped by status — replaces the Dataview blocks that only render in Obsidian.
- One page per task / runbook, full-text searchable.
- Mobile + desktop friendly (Material theme + PWA-installable).
- Only people on the Cloudflare Access policy can view it (you, by default — extend by adding emails or groups).
- Auto-rebuilds on every push to
nightly(the docs branch); preview builds on every PR.
One-time setup¶
1. Connect the repo to Cloudflare Pages (~5 min)¶
- Cloudflare dashboard → Workers & Pages → Create application → Pages → Connect to Git.
- Authorize Cloudflare's GitHub app on
girafeev1/ArtifactoftheEstablisherif you haven't yet. - Pick the repo. Then in Set up builds and deployments:
| Field | Value |
|---|---|
| Project name | eop-task-surface (or whatever — this becomes a subdomain on pages.dev) |
| Production branch | nightly |
| Framework preset | None |
| Build command | pip install -r requirements-docs.txt && python scripts/build-docs-site.py && mkdocs build |
| Build output directory | site |
| Root directory | (leave blank — repo root) |
| Environment variable | PYTHON_VERSION = 3.12 |
- Save and Deploy. The first build takes ~90 sec (pip install dominates).
After success the site is reachable at
https://eop-task-surface.pages.dev/. That's the Cloudflare default
URL — public so far. The next two steps make it private + clean.
2. Point a custom subdomain at it (~2 min)¶
- In the Pages project → Custom domains → Set up a custom domain.
- Enter
tasks.theestablishers.com(or any other subdomain you prefer —s.theestablishers.com,t.theestablishers.com, etc.). - Cloudflare auto-creates the CNAME record (since the domain's already on Cloudflare's DNS). Takes ~30 sec to issue the TLS cert.
Now https://tasks.theestablishers.com/ serves the site.
3. Gate it with Cloudflare Access (~3 min)¶
Without this step, anyone with the URL can read the site. With it, visitors must auth via email-OTP (or Google SSO, GitHub SSO, etc.) and only listed identities can pass.
- Zero Trust dashboard → Access → Applications → Add an application → Self-hosted.
- Configure:
| Field | Value |
|---|---|
| Application name | EOP Task Surface |
| Session duration | 30 days (so the phone re-auths once a month) |
| Application domain | tasks.theestablishers.com |
- Continue to Policies. Add policy:
- Policy name:
owner-only - Action: Allow
-
Configure rules → Include → Emails → add your email (extend later with more emails as needed)
-
Continue → Identity providers → tick at least One-time PIN (email OTP — no setup). If you want Google SSO too, add Google as an identity provider under Settings → Authentication and tick it here.
-
Add application → done.
How you'll access it on your phone¶
First visit:
1. Open https://tasks.theestablishers.com/ in any mobile browser.
2. Cloudflare Access shows a sign-in page → Send code → enter
your email → check email → paste the 6-digit code.
3. Redirected to the docs site. Session cookie is set for 30 days.
Quality-of-life: - iOS Safari: Share → "Add to Home Screen" → the docs site behaves like an installed app (own icon, fullscreen, no browser chrome). - Android Chrome: ⋮ menu → "Install app" → same effect.
After 30 days you'll re-do the OTP once. You can shorten or lengthen this in the Access policy.
Ongoing — what triggers a rebuild?¶
- Every push to
nightly→ Production deployment, replaces what's served attasks.theestablishers.com. - Every PR → Preview deployment at a per-PR URL like
https://<branch-slug>.eop-task-surface.pages.dev/. Cloudflare comments the URL on the PR. Useful for reviewing big task changes before they're public. - Manual: Pages project → Deployments → Retry deployment / Create deployment on any commit.
How to revoke / pause¶
- Pause public access without touching the site: Access policy → edit policy → change action to Block (or remove your email). Everyone gets bounced on next visit.
- Take the site down entirely: Pages project → Settings → Builds & deployments → Disable builds. Existing pages keep serving until you also delete the project.
- Delete cleanly: Pages project → Settings → Delete project. The Access application + CNAME record can be deleted separately.
Adding more people¶
Access policy → edit → Include → Emails → add additional addresses
(or switch to "Emails ending in" for @theestablishers.com, or add a
group from your identity provider). No site changes needed.
Troubleshooting¶
- Build failed in Cloudflare: open the build logs from the
deployment page. Common causes are
requirements-docs.txtversions drifting or a task file with broken YAML frontmatter (the build script logs[docs-build] WARN: bad frontmatter in T-NNN.md— fix the source file or live with that task being absent from the board). - Site loads but Task Board is empty: the build script can't find
frontmatter — verify each
T-NNN.mdstarts with a---\n…\n---block including at minimumstatus:anduid:fields. - 403 Forbidden on access: Cloudflare Access policy doesn't include your email; edit the policy.
- Custom domain shows certificate warning: TLS issuance is async; give it ~5 min after adding the custom domain in step 2.
Local preview (optional)¶
If you want to render the site on your laptop before pushing:
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements-docs.txt
python scripts/build-docs-site.py
mkdocs serve # http://127.0.0.1:8000
Live-reloads on file changes in _docs_site/.