Skip to main content

ADR-0052: Docusaurus + Cloudflare Pages for Documentation Publishing

Status: ✅ Accepted Date: 2025-10-28 Decision Maker: Tech Lead Category: Documentation Infrastructure


Context

TVL Platform has comprehensive documentation in /docs/ following industry standards. We need to:

  1. Publish documentation for team members, executives, and stakeholders
  2. Free hosting - Cannot justify $99+/month for documentation at MVP stage
  3. Access control - Restrict access to authorized users (not public)
  4. GitHub auto-sync - Documentation auto-updates from Git commits
  5. Beautiful UI - Professional presentation for stakeholders
  6. OpenAPI support - Render API documentation from /docs/reference/api/openapi.yaml
  7. Zero DevOps overhead - Team focuses on product, not docs infrastructure

Decision

Use Docusaurus + Cloudflare Pages for documentation publishing.

Architecture

Source (GitHub)                    Published (Cloudflare)
┌─────────────────────┐ ┌──────────────────────┐
│ /docs/ │ │ Cloudflare Pages │
│ ├── specifications/│ Push │ ┌────────────────┐ │
│ ├── guides/ │──────────>│ │ Docusaurus │ │
│ ├── architecture/ │ GitHub │ │ Static Site │ │
│ ├── reference/ │ Action │ └────────────────┘ │
│ └── api/ │ │ │
└─────────────────────┘ │ Cloudflare Access │
│ (Google SSO) │
└──────────────────────┘

Components

1. Docusaurus (Static Site Generator)

  • React-based documentation framework
  • Markdown-native
  • OpenAPI plugin support
  • Versioning built-in
  • Search included

2. Cloudflare Pages (Hosting)

  • Free tier: Unlimited bandwidth, 500 builds/month
  • GitHub integration: Auto-deploys on commit
  • Global CDN: Fast page loads worldwide
  • Custom domains: Free SSL
  • Zero DevOps: Fully managed

3. Cloudflare Access (Authentication)

  • Free tier: Up to 50 users
  • Google SSO: Sign in with Google (existing accounts)
  • Zero-trust security: No VPN needed
  • Access policies: Team vs. stakeholder views
  • Audit logs: Track who accessed what

Rationale

Why Docusaurus?

  1. Free - Open source (MIT license)
  2. React-based - Aligns with frontend stack (React + Next.js)
  3. Markdown-first - Source of truth remains in /docs/
  4. OpenAPI plugin - Render API docs from openapi.yaml
  5. Versioning - Built-in support for MVP.0, MVP.1, MVP.2, V1, V2, V3
  6. Search - Algolia DocSearch (free for open source docs, or local search)
  7. Active community - Meta-backed, large ecosystem
  8. Fast builds - Static site generation

Why Cloudflare Pages?

  1. Free tier - Unlimited bandwidth (vs. Vercel 100GB limit, Netlify 100GB limit)
  2. GitHub auto-deploy - Push to main → auto-publish
  3. Global CDN - 200+ edge locations
  4. Zero config - Detects Docusaurus automatically
  5. Preview deployments - Every PR gets a preview URL
  6. Custom domains - Free SSL via Let's Encrypt
  7. Build minutes - 500 builds/month free (vs. Vercel 100 minutes)

Why Cloudflare Access?

  1. Free tier - Up to 50 users (sufficient for MVP phase)
  2. Google SSO - Team already uses Google Workspace
  3. Zero infrastructure - No auth code to write/maintain
  4. Zero-trust model - Works from anywhere (no VPN)
  5. Access policies - Define who can access which paths
  6. Audit logs - Compliance-ready access tracking

Alternatives Considered

Alternative 1: GitBook ($99-249/month)

Why Rejected:

  • Cost: $99/month = $1,188/year (cannot justify at MVP stage)
  • Vendor lock-in: Proprietary platform
  • Overkill: Team doesn't need enterprise features

When to reconsider:

  • Revenue > $100k/month
  • Need enterprise SSO (SAML)
  • Executive presentation features justify cost

Alternative 2: MkDocs + Cloudflare Pages

Why Rejected:

  • Python dependency: Not aligned with Node.js/TypeScript stack
  • Limited plugins: Less mature ecosystem than Docusaurus
  • No React: Can't reuse frontend components

When to reconsider:

  • Team has strong Python expertise
  • Want simpler, lighter-weight solution

Alternative 3: VitePress + Cloudflare Pages

Why Rejected:

  • ⚠️ Less mature: Newer than Docusaurus (v1.0 released 2023)
  • ⚠️ Smaller ecosystem: Fewer plugins and themes
  • ⚠️ Vue-based: Not aligned with React stack

When to reconsider:

  • Team prefers Vue over React
  • Want faster build times (Vite vs. Webpack)

Alternative 4: Self-hosted Wiki.js

Why Rejected:

  • DevOps overhead: Requires server, database, backups
  • Cost: $10-50/month hosting + maintenance time
  • Not Git-first: Manual import/export workflow

Alternative 5: Notion (Published Pages)

Why Rejected:

  • Not Git-based: Source of truth moves from GitHub to Notion
  • No markdown control: WYSIWYG editor conflicts with developer workflow
  • Limited customization: Can't control UI/UX

Implementation

Phase 1: Docusaurus Setup (2-3 hours)

1. Install Docusaurus

# Create Docusaurus project
npx create-docusaurus@latest docs-site classic --typescript

# Move to monorepo structure
mkdir -p apps/docs
mv docs-site/* apps/docs/

2. Configure to use existing /docs/ content

// apps/docs/docusaurus.config.ts
export default {
title: 'TVL Platform Documentation',
tagline: 'Multi-tenant vacation rental management SaaS',
url: 'https://docs.thevillalife.com',
baseUrl: '/',

// Use existing /docs/ as source
docs: {
path: '../../docs',
routeBasePath: '/',
sidebarPath: './sidebars.ts',
},

// OpenAPI plugin
plugins: [
[
'docusaurus-plugin-openapi-docs',
{
id: 'api',
docsPluginId: 'classic',
config: {
api: {
specPath: '../../docs/reference/api/openapi.yaml',
outputDir: './docs/api',
},
},
},
],
],

themeConfig: {
navbar: {
title: 'TVL Platform',
items: [
{ to: '/specifications', label: 'Specifications', position: 'left' },
{ to: '/guides', label: 'Guides', position: 'left' },
{ to: '/architecture', label: 'Architecture', position: 'left' },
{ to: '/reference', label: 'Reference', position: 'left' },
{ to: '/api', label: 'API', position: 'left' },
],
},
footer: {
copyright: `© ${new Date().getFullYear()} The Villa Life. All rights reserved.`,
},
},
};

3. Install OpenAPI plugin

cd apps/docs
npm install docusaurus-plugin-openapi-docs docusaurus-theme-openapi-docs

Phase 2: Cloudflare Pages Setup (1 hour)

1. Create Cloudflare Pages project

  • Go to Cloudflare Dashboard → Pages
  • Click "Create a project"
  • Connect GitHub repository: your-org/the-villa-life
  • Select branch: main
  • Build settings:
    • Build command: cd apps/docs && npm run build
    • Build output directory: apps/docs/build
    • Root directory: /

2. Configure custom domain (optional)

  • Add custom domain: docs.thevillalife.com
  • Cloudflare auto-configures DNS and SSL
  • Wait 5 minutes for propagation

3. Test deployment


Phase 3: Cloudflare Access Setup (30 minutes)

1. Enable Cloudflare Access

  • Cloudflare Dashboard → Zero Trust → Access
  • Enable Google SSO:
    • Add Google OAuth app (free Google Workspace account)
    • Callback URL: https://<your-team-name>.cloudflareaccess.com/cdn-cgi/access/callback

2. Create access policies

Policy 1: Team (Full Access)

Name: Team - Full Access
Application: docs.thevillalife.com
Action: Allow
Include:
- Emails ending in: @thevillalife.com
- Email: contractor@example.com
Exclude: (none)
Path: /* (all paths)

Policy 2: Stakeholders (Limited Access)

Name: Stakeholders - Specifications Only
Application: docs.thevillalife.com
Action: Allow
Include:
- Email: investor@example.com
- Email: ceo@example.com
Exclude: (none)
Path:
- /specifications/*
- /architecture/* (high-level only)

Policy 3: Block Implementation Details

Name: Block - Implementation Details (Stakeholders)
Application: docs.thevillalife.com
Action: Block
Include:
- Email: investor@example.com
Exclude: (none)
Path:
- /guides/* (implementation guides)
- /reference/database/* (database schemas)
- /reference/decisions/* (ADRs)

3. Test access control

  • Sign in as team member → Full access
  • Sign in as stakeholder → Specifications only, guides blocked

Phase 4: GitHub Actions (30 minutes)

# .github/workflows/docs.yml
name: Deploy Documentation

on:
push:
branches: [main]
paths:
- 'docs/**'
- 'apps/docs/**'

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 20

- name: Install dependencies
run: |
cd apps/docs
npm ci

- name: Build Docusaurus
run: |
cd apps/docs
npm run build

- name: Deploy to Cloudflare Pages
uses: cloudflare/pages-action@v1
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: tvl-docs
directory: apps/docs/build

Cost Analysis

Year 1 Costs

ComponentPlanCostNotes
DocusaurusOpen Source$0Free forever
Cloudflare PagesFree Tier$0500 builds/month, unlimited bandwidth
Cloudflare AccessFree Tier$0Up to 50 users
Custom Domain(existing)$0Already own thevillalife.com
Setup Time4 hours × $100/hr$400 (one-time)Developer time
Maintenance1 hour/month × $100/hr$1,200/yearUpdates, content
TOTAL YEAR 1$1,600Setup + maintenance

Comparison vs. Alternatives

SolutionYear 1 CostYear 2+ Cost
Docusaurus + Cloudflare (chosen)$1,600$1,200/year
GitBook Team$1,188 + $800 setup = $1,988$1,188/year
GitBook Business$2,988 + $800 setup = $3,788$2,988/year
Self-hosted Wiki.js$600 hosting + $2,000 setup = $2,600$720/year

Savings: $388-2,188 in Year 1 vs. alternatives


Consequences

Positive

  1. Zero recurring cost - Free tier covers MVP phase (< 50 users)
  2. Fast implementation - 4 hours vs. 8-16 hours for self-hosted
  3. Zero DevOps - No servers, databases, or backups to manage
  4. Production-ready - Cloudflare CDN, 99.99% uptime SLA
  5. Scales with team - Free up to 50 users, $3/user/month after
  6. Source control - Docs remain in Git (single source of truth)
  7. React alignment - Aligns with frontend stack

Negative

  1. ⚠️ Setup time required - 4 hours to configure Docusaurus + Cloudflare
  2. ⚠️ React dependency - Must maintain React-based docs site
  3. ⚠️ Limited access control UI - Cloudflare Access less polished than GitBook
  4. ⚠️ 50-user limit - Must upgrade to paid plan ($3/user/month) if team > 50

Mitigations

  1. Setup time: One-time investment, well-documented
  2. React dependency: Aligns with existing stack, low maintenance
  3. Access control: Sufficient for MVP needs, can upgrade later
  4. User limit: Can upgrade to paid plan or migrate to self-hosted solution

Success Metrics

Setup Phase (Week 1)

  • ✅ Docusaurus builds successfully from /docs/
  • ✅ Cloudflare Pages deploys automatically on commit
  • ✅ Cloudflare Access restricts access to authorized users
  • ✅ OpenAPI docs render correctly

Adoption Phase (Month 1)

  • ✅ 100% of team using docs site (vs. raw GitHub)
  • ✅ At least 1 stakeholder has accessed docs
  • ✅ Documentation updates auto-publish within 5 minutes
  • ✅ Zero maintenance hours spent

Long-term (Quarter 1)

  • ✅ Used in investor/board presentations
  • ✅ API docs used by integration partners
  • ✅ Team satisfaction: "Docs are easy to update and share"
  • ✅ Still on free tier (< 50 users, < 500 builds/month)

Migration Path

If Cloudflare Access limit exceeded (> 50 users):

Option 1: Upgrade to paid plan

  • Cost: $3/user/month
  • 100 users = $300/month = $3,600/year

Option 2: Migrate to self-hosted auth

  • Implement NextAuth with Google OAuth
  • Deploy Docusaurus to Vercel/Netlify
  • Cost: $20/month hosting + 8 hours setup

Option 3: Migrate to GitBook

  • Export markdown from Docusaurus
  • Import to GitBook
  • Cost: $99/month = $1,188/year

Recommendation: Start with free tier, upgrade to paid Cloudflare Access if needed (still cheaper than GitBook)


Review Date

Next Review: 2025-04-28 (6 months)

Review Criteria:

  • Are we still under 50 users? (Free tier limit)
  • Are we exceeding 500 builds/month? (Free tier limit)
  • Is team satisfied with access control UX?
  • Do we need enterprise features (SSO, advanced policies)?

If exceeded limits: Evaluate upgrade to paid Cloudflare Access vs. GitBook


References


Last Updated: 2025-10-28 Status: ✅ Accepted Implementation Status: 🚧 Pending