Skip to content

MkDocs + Cloudflare Pages: Full Installation Guide

End-to-end setup for the eco|monetize internal documentation platform. Covers nameserver migration, Pages project creation, GitHub Actions wiring, and Cloudflare Access. Written from a live install completed 2026-04-22 — UI descriptions match the actual Cloudflare interface as of that date.

Deployment targets

Site Cloudflare project URL Auth
Internal ops docs (Phase 1) eco-docs-internal docs.ecomonetize.com Cloudflare Access — invite only
Public ERI docs (Phase 2) eco-docs-public help.ecomonetize.com Public

This guide covers Phase 1. Phase 2 follows the same steps with different project name and domain.


Part 1 — GoDaddy → Cloudflare Nameserver Migration

This is the single blocking dependency for everything else. Both subdomains and Cloudflare Access require Cloudflare to be authoritative for ecomonetize.com.

Time: 15 min setup + up to 48 hrs propagation (typically 1–4 hrs)

1.1 Add the domain to Cloudflare

  1. Log in to dash.cloudflare.com as info@ecomonetize.com
  2. Click Add a domain (top of the home dashboard)
  3. Enter ecomonetize.comContinue
  4. Select Free plan → Continue

Cloudflare auto-scans your GoDaddy DNS records and imports them.

1.2 Review imported DNS records

Cloudflare shows you the records it found. Before continuing, verify:

  • A records — your existing root/www entries are present
  • MX records — Google Workspace mail records are present (aspmx.l.google.com and alternates). If missing, add them manually now — email will break after the nameserver switch if these are absent.
  • TXT records — SPF, DKIM, DMARC, Google site verification all imported

When satisfied, click Continue.

1.3 Get your Cloudflare nameservers

Cloudflare assigns two nameservers unique to your account. They look like:

danner.ns.cloudflare.com
kate.ns.cloudflare.com

Copy both. You need them in the next step.

1.4 Update nameservers in GoDaddy

  1. Log in to godaddy.comMy Products → find ecomonetize.comDNS
  2. Scroll to Nameservers → click Change
  3. Select Enter my own nameservers (advanced)
  4. Delete GoDaddy's nameservers, enter your two Cloudflare nameservers
  5. Click Save and confirm the warning

1.5 Wait for propagation

  • Typical: 1–4 hours. Maximum: 48 hours.
  • Check status: whatsmydns.net → search ecomonetize.com type NS
  • Cloudflare sends a confirmation email to info@ecomonetize.com when the zone goes Active

1.6 Verify the zone is Active

  1. dash.cloudflare.com → click ecomonetize.com
  2. Domains list shows ecomonetize.com with status Active
  3. The domain overview page shows "Your domain is now protected by Cloudflare"

1.7 Add DNS records for docs subdomains

Once Active, go to DNS → RecordsAdd record and add:

Type Name Content Proxy
CNAME docs eco-docs-internal.pages.dev Proxied (orange cloud)
CNAME help eco-docs-public.pages.dev Proxied (orange cloud) — add when Phase 2 is ready

Proxied is required. Non-proxied CNAMEs bypass Cloudflare Access.


Part 2 — Create the Cloudflare Pages Project

Important: Do NOT use the Git-connected path. Cloudflare's new UI requires a "Deploy command" for Git-connected projects, which conflicts with our GitHub Actions deploy approach. Use Direct Upload (drag and drop) to create the project shell, then GitHub Actions takes over all future deploys.

2.1 Navigate to Pages creation

  1. dash.cloudflare.com → left sidebar → Workers & Pages
  2. Click Create (top right)
  3. You land on "Ship something new" — this is the Workers creation screen by default
  4. Scroll to the bottom and click "Get started" next to "Looking to deploy Pages?"

2.2 Choose Direct Upload

You'll see: "Get started with Pages. How would you like to begin?"

  • Import an existing Git repository — do NOT use this
  • Drag and drop your files — click this

2.3 Name the project

Enter project name: eco-docs-internal

You'll see: "Your project will be deployed to eco-docs-internal.pages.dev"

2.4 Create a placeholder zip to satisfy the upload requirement

Cloudflare requires at least one file to create the project. Run this in your terminal to create a placeholder zip:

mkdir -p ~/Desktop/eco-docs-placeholder && \
echo '<html><body>eco-docs-internal placeholder</body></html>' > ~/Desktop/eco-docs-placeholder/index.html && \
cd ~/Desktop && \
zip -r eco-docs-placeholder.zip eco-docs-placeholder && \
rm -r ~/Desktop/eco-docs-placeholder

This puts eco-docs-placeholder.zip on your Desktop.

2.5 Upload and deploy

  1. Drag eco-docs-placeholder.zip from your Desktop into the Cloudflare upload area
  2. Click Deploy site

You land on the project dashboard showing: - Workers & Pages / eco-docs-internal - Production deployment at eco-docs-internal.pages.dev — status: success

The placeholder content doesn't matter. GitHub Actions will overwrite it on the first real deploy.


Part 3 — Attach the Custom Domain

3.1 Open Custom Domains

On the eco-docs-internal project page: click the Custom domains tab at the top.

3.2 Enter the domain

Click Set up a custom domain → enter docs.ecomonetize.comContinue

3.3 Confirm the DNS record

Cloudflare shows a "Confirm new DNS record" screen. It detects your existing CNAME (from Part 1 Step 1.7) and confirms:

Type Name Content TTL
CNAME docs eco-docs-internal.pages.dev Auto

Click Activate domain.

Cloudflare verifies the CNAME and activates the custom domain. https://docs.ecomonetize.com will route to the Pages project once DNS propagation is complete.


Part 4 — Wire Up GitHub Actions

This is what makes future deploys automatic. Every push to main that changes docs content will build and deploy to Cloudflare Pages without any manual steps.

4.1 Get your Cloudflare API token

Create a minimal-scope token dedicated to Pages deploys. Do NOT use the "Edit Cloudflare Workers" template — it includes unrelated permissions and the resulting token may lack the correct Pages scope.

  1. dash.cloudflare.com → top-right profile icon → My Profile → left sidebar → API Tokens
  2. Click + Create Token → scroll to bottom → Create Custom TokenGet started
  3. Token name: MkDocs Deploy
  4. Under Permissions, add one row:
  5. Dropdown 1: Account
  6. Dropdown 2: Cloudflare Pages
  7. Dropdown 3: Edit
  8. Under Account Resources: Include → select ecomonetize
  9. Click Continue to summaryCreate Token
  10. Copy the token value — shown only once
  11. Save to 1Password → item name: Cloudflare-MkDocs-Deploy → paste token into the credential field

To retrieve later: open 1Password → search Cloudflare-MkDocs-Deploy → copy the credential field value.

Security: Never paste the token value into chat or a terminal command that will be logged. If a token is accidentally exposed, rotate it immediately: My Profile → API Tokens → find the token → Roll. Update the 1Password item and the GitHub secret with the new value.

4.2 Get your Account ID

  1. dash.cloudflare.com → click ecomonetize.com zone
  2. Scroll to the bottom of the zone overview page — Account ID and Zone ID are listed there
  3. Copy the Account ID (Zone ID is not needed)

Alternatively, read it from your browser URL bar: dash.cloudflare.com/{account_id}/...

4.3 Add GitHub secrets

In the GitHub repo (eco-monetize/claude):

  1. Click the Settings tab (top nav bar)
  2. Left sidebar → scroll to "Security and quality" section → click Secrets and variables (has a dropdown arrow) → click Actions
  3. To add a new secret: click New repository secret → enter name and value → Add secret
  4. To update an existing secret: find the secret row → click the pencil icon on the right → paste new value → Update secret
Secret name Value
CLOUDFLARE_API_TOKEN Token from Step 4.1 (retrieve from 1Password → Cloudflare-MkDocs-Deploy → credential field)
CLOUDFLARE_ACCOUNT_ID Account ID from Step 4.2

Add or update each secret separately.

4.4 Verify the GitHub Actions workflow

The workflow file at .github/workflows/docs.yml should deploy via npx wrangler@latest with env vars set directly — do not use cloudflare/wrangler-action, which pins an old wrangler version (3.90.0) with broken auth handling for token-scoped deploys. The deploy step should look like:

- name: Deploy to Cloudflare Pages
  env:
    CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
    CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
  run: npx --yes wrangler@latest pages deploy site --project-name=eco-docs-internal --commit-dirty=true

The workflow should NOT contain: - actions/upload-pages-artifact - actions/deploy-pages - permissions: pages: write - cloudflare/wrangler-action (pins old wrangler — see troubleshooting)

4.5 Trigger the first real deploy

Push any change to main on a docs-relevant path. The GitHub Actions workflow runs, builds the MkDocs site, and deploys to Cloudflare Pages. The placeholder content gets replaced.


Part 5 — Configure Cloudflare Access (Phase 1 only)

This gates docs.ecomonetize.com behind email-based one-time PIN login. Invited users get a code emailed to them — no VPN, no Tailscale, no password required.

5.1 Open Zero Trust

dash.cloudflare.com → left sidebar → Zero Trust (under "Protect & Connect")

First-time setup only: If this is your first time in Zero Trust, you'll be prompted to: 1. Choose your team name — enter ecomonetizeNext. This creates ecomonetize.cloudflareaccess.com as your login domain. 2. Choose a plan — select Free (covers up to 50 users, sufficient for team + investors + contractors) 3. You'll land on a "Get started with Zero Trust" screen with 4 options.

5.2 Navigate to Applications

From the Zero Trust "Get started" screen: - Click Get started next to "Set up secure access to private apps from any browser" - On the next screen ("What type of application are you securing?"), click Continue next to "Connect a private web application"

Or navigate directly: left sidebar → AccessApplicationsAdd an application

5.3 Choose application type

Select Self-hosted and privateContinue with Self-hosted and private

Do NOT use the "Tunnel" wizard that appears in some navigation paths — it asks for internal hostname and port, which is for self-hosted servers, not Cloudflare Pages.

5.4 Configure the application destination

The form uses split Subdomain + Domain fields (not a single domain field):

  • Subdomain: docs
  • Domain: ecomonetize.com (select from dropdown)
  • Path: leave blank

5.5 Create the access policy

Scroll to Access policies → click Create new policy:

  • Policy name: Team + Approved External
  • Action: Allow
  • Include rule: Emails → add each authorized email address (team, investors, contractors)

Click Save Policy. The policy appears in the list with Action: ALLOW.

5.6 Authentication settings

In the Authentication section: - Accept all available identity providers — leave as-is (toggles based on your identity provider config) - Apply instant authentication — ON (skips provider selection when only one method is available)

This configures one-time PIN via email as the login method. Users receive a code at their authorized email address.

5.7 Save the application

Details section (bottom of page): - Name: docs (auto-generated from subdomain — leave as-is) - Session duration: 24 hours

Click Create. The Applications list shows docsdocs.ecomonetize.com → SELF-HOSTED with 1 policy assigned.

Adding a new user later: Zero Trust → Access → Applications → docs → Edit → Access policies → edit Team + Approved External → add their email.


Post-install checklist

  • [ ] ecomonetize.com zone Active in Cloudflare Domains list
  • [ ] Email still working — send test to/from info@ecomonetize.com
  • [ ] DNS Records show docs CNAME → eco-docs-internal.pages.dev (Proxied)
  • [ ] eco-docs-internal Pages project exists and has a production deployment
  • [ ] Custom domain docs.ecomonetize.com activated in Pages project
  • [ ] GitHub secrets CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID set
  • [ ] GitHub Actions workflow deploys successfully on push
  • [ ] Cloudflare Access policy configured on docs.ecomonetize.com
  • [ ] docs.ecomonetize.com loads site and Access gate appears on first visit

Troubleshooting

Problem Fix
Cloudflare UI shows Workers creation instead of Pages Scroll to bottom of "Ship something new" screen → click "Get started" next to "Looking to deploy Pages?"
Git-connected path requires a Deploy command Don't use the Git path. Use "Drag and drop your files" instead. Our deploys are handled by GitHub Actions.
Cloudflare requires a folder or zip, not a single file Create a zip: mkdir tmp && echo '<html><body>placeholder</body></html>' > tmp/index.html && zip -r placeholder.zip tmp
Email stopped working after nameserver migration MX records didn't import. Add manually in Cloudflare DNS: aspmx.l.google.com (priority 1), alt1–alt4.aspmx.l.google.com (priority 5–10)
docs.ecomonetize.com not resolving Check CNAME is Proxied (orange cloud). Non-proxied bypasses Cloudflare Access and won't route correctly.
Main site (ecomonetize.com) broken after nameserver migration ecomonetize.com is hosted on Lovable. Lovable requires the root A record and www A record to be DNS only (not Proxied) in Cloudflare. Set both to DNS only — Lovable handles SSL directly. Only the docs CNAME should be Proxied.
Turning off proxy breaks docs Access gate When Lovable support says "turn off proxy," that applies only to the root A records. The docs CNAME must stay Proxied (orange cloud) for Cloudflare Access to intercept requests.
GitHub Actions deploy fails — Authentication error [code: 10000] Three possible causes: (1) Token missing Account → Cloudflare Pages → Edit permission — edit the token and add it. (2) cloudflare/wrangler-action pins wrangler 3.90.0 which has broken auth for token-scoped deploys — replace with npx --yes wrangler@latest per Step 4.4. (3) Wrong token in GitHub secret — verify CLOUDFLARE_API_TOKEN matches the value in 1Password → Cloudflare-MkDocs-Deploy → credential field. GitHub blanks the field when editing; just paste the correct value again to confirm.
GitHub Actions deploy fails — Invalid access token [code: 9109] The token value in the GitHub secret is wrong or stale. Open 1Password → Cloudflare-MkDocs-Deploy → copy the credential field → GitHub → Settings → Security and quality → Secrets and variables → Actions → CLOUDFLARE_API_TOKEN → pencil → paste → Update secret. Note: editing a Cloudflare token's permissions does NOT change its value; only Rolling does.
Multiple similar tokens in 1Password causing confusion Keep only one token for Pages deploy: Cloudflare-MkDocs-Deploy. Delete any old rotated tokens from both 1Password and the Cloudflare API Tokens dashboard (My Profile → API Tokens). The broad-scope "Cloudflare Agent Token" is auto-generated for MCP integrations — leave it alone.
Deploy fails — search_index.json is 33.5 MiB Cloudflare Pages rejects files over 25 MiB. The MkDocs search index bloats when large content (e.g. session transcript archives) is included. Remove the offending content from the docs build — do not copy session archives into docs/ in the workflow.
GitHub Actions deploy fails Check CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID secrets are set. Verify project name matches exactly: eco-docs-internal.
Access gate not appearing Check Zero Trust → Access → Applications. Confirm docs.ecomonetize.com is listed with an active Allow policy.
Cloudflare zone stuck on "Pending" Nameserver propagation not complete. Check whatsmydns.net for NS records. Wait and recheck.

Phase 2 differences (help.ecomonetize.com)

  • Cloudflare Pages project name: eco-docs-public
  • CNAME: helpeco-docs-public.pages.dev
  • No Cloudflare Access policy — public site
  • Separate GitHub Actions workflow targeting different content paths
  • Requires CMO (Michelle) to author initial ERI content before first deploy

Last verified

2026-04-23 — documentation.engineering. First successful deploy confirmed. Step 4.4 rewritten: cloudflare/wrangler-action replaced with npx --yes wrangler@latest — wrangler-action pins 3.90.0 which has broken auth for token-scoped deploys; wrangler 4.84.1 resolves correctly. Troubleshooting expanded: code: 9109 (invalid token value), multiple-token confusion, wrangler-action version issue. workflow_dispatch trigger added to workflow for manual reruns.