Migrating Docusaurus — Self-Hosted to GitHub + Cloudflare Pages
This module walks you through the complete, hands-on migration from a self-hosted Docusaurus installation to a GitHub + Cloudflare Pages deployment — the exact workflow the author has personally tested and runs in production.
Migration Overview
flowchart LR
A["Self-Hosted Docusaurus\n(Docker on VPS)"] -->|"Step 1: Init Git"| B["Local Git Repo\n(existing files)"]
B -->|"Step 2: Push to GitHub"| C["GitHub Repository\n(private or public)"]
C -->|"Step 3: Connect"| D["Cloudflare Pages\n(dashboard)"]
D -->|"Step 4: Configure"| E["Build Settings\n(npm run build / build/)"]
E -->|"Step 5: Deploy"| F["Live on\nyour-project.pages.dev"]
F -->|"Step 6: Custom domain"| G["docs.yourdomain.com\n(HTTPS, DDoS, global CDN)"]
style A fill:#6b7280,color:#fff,stroke:#4b5563
style C fill:#24292e,color:#fff,stroke:#555
style D fill:#f6821f,color:#fff,stroke:#e5711e
style G fill:#16a34a,color:#fff,stroke:#15803d
Pre-Migration Checklist
Before you start, confirm:
- You have a GitHub account (free tier is fine)
- You have a Cloudflare account (free tier is fine)
- Your domain is managed in Cloudflare DNS (for custom domain setup)
- Your Docusaurus project builds successfully (
npm run buildproduces abuild/directory) -
gitis installed on your local machine
Step 1 — Prepare Your Docusaurus Repository
1a. Initialize Git (if not already a repo)
If your Docusaurus files are not yet in a Git repository:
# Navigate to your Docusaurus root
cd /path/to/your/docusaurus/site
# Initialize
git init
# Create .gitignore
cat > .gitignore << 'EOF'
node_modules/
build/
.docusaurus/
.cache-loader/
.env
.env.local
EOF
# Stage all files
git add .
# Initial commit
git commit -m "chore: initial commit — Docusaurus site"
1b. Verify Your Build Works
# Install dependencies
npm install
# Build the site
npm run build
# Expected output:
# [SUCCESS] Generated static files in "build".
# [INFO] Use `npm run serve` to test your build locally.
# Optional: serve locally to verify
npm run serve
# → http://localhost:3000
The build/ directory is what Cloudflare Pages will serve. Ensure it generates correctly without errors before proceeding.
1c. Check docusaurus.config.js
For Cloudflare Pages deployment, the url and baseUrl must be set correctly:
const config = {
// Set to your custom domain (or pages.dev URL during initial setup)
url: 'https://docs.yourdomain.com',
// If deploying at root, use '/'
// If deploying to a subdirectory (rare on Pages), use '/subdirectory/'
baseUrl: '/',
// ... rest of config
};
Step 2 — Create a GitHub Repository
Via GitHub Web UI
- Go to github.com/new
- Name your repository (e.g.,
my-docs) - Choose Private or Public — Cloudflare Pages supports both
- Do NOT initialize with README (your repo already has files)
- Click Create repository
Via GitHub CLI
# Install gh CLI if not present
# https://cli.github.com/
# Authenticate
gh auth login
# Create private repository
gh repo create my-docs --private --source=. --remote=origin --push
# Or create public repository
gh repo create my-docs --public --source=. --remote=origin --push
Push Existing Repository
# Add GitHub as the remote origin
git remote add origin https://github.com/your-username/my-docs.git
# Rename branch to main (if needed)
git branch -M main
# Push
git push -u origin main
Step 3 — Connect to Cloudflare Pages
Via Cloudflare Dashboard
- Log in to dash.cloudflare.com
- Go to Workers & Pages → Create → Pages tab
- Click Connect to Git
- Authorize the Cloudflare Pages GitHub App (first time only)
- Select your repository (
my-docs) - Click Begin setup
Build Configuration
| Field | Value for Docusaurus |
|---|---|
| Project name | my-docs (becomes my-docs.pages.dev) |
| Production branch | main |
| Framework preset | Docusaurus (auto-detected) |
| Build command | npm run build |
| Build output directory | build |
| Root directory | / (leave blank unless monorepo) |
Select Docusaurus from the framework dropdown and Cloudflare will automatically fill in the build command and output directory. You can override them manually if needed.
Environment Variables (Optional)
If your build needs env variables (e.g., Algolia keys, custom API endpoints):
| Variable | Example |
|---|---|
NODE_VERSION | 20 |
ALGOLIA_APP_ID | your-algolia-app-id |
ALGOLIA_API_KEY | your-algolia-api-key |
Set these under Settings → Environment variables in the Pages project.
Save and Deploy
Click Save and Deploy. Cloudflare will:
- Clone your repository
- Run
npm run build - Deploy the
build/directory to the edge
First build typically takes 2–4 minutes.
Step 4 — Monitor the Build
Watch the build in real-time:
Workers & Pages → your-project → Deployments → (latest)
Build log example (what to expect for Docusaurus):
12:00:01 [INFO] Cloning repository...
12:00:05 [INFO] Installing dependencies from package-lock.json
12:01:20 [INFO] Running build command: npm run build
12:01:21 [INFO] [docusaurus] Starting the production build...
12:02:45 [SUCCESS] Generated static files in "build".
12:02:45 [INFO] Generated 147 pages in 84.621 seconds.
12:02:50 [INFO] Uploading 147 files to Cloudflare edge...
12:03:02 [SUCCESS] Deployment live at: https://abc123.my-docs.pages.dev
If the build fails, see Troubleshooting below.
Step 5 — Add a Custom Domain
Automatic DNS (Cloudflare-managed domain)
If your domain's DNS is already in Cloudflare:
- Go to your Pages project → Custom domains tab
- Click Set up a custom domain
- Enter
docs.yourdomain.com - Click Continue — Cloudflare automatically creates the CNAME record:
docs.yourdomain.com CNAME my-docs.pages.dev
SSL is provisioned within ~60 seconds.
Manual DNS (External registrar)
If your DNS is NOT managed by Cloudflare, add this CNAME manually at your registrar:
Host: docs
Type: CNAME
Value: my-docs.pages.dev
TTL: Auto
Then add the domain in Cloudflare Pages dashboard and verify ownership.
Step 6 — Set Up Automatic Deployments
Once connected, the workflow is entirely automatic:
# Edit your docs
vim docs/getting-started.md
# Commit
git add docs/getting-started.md
git commit -m "docs: update getting started guide"
# Push — this triggers a Cloudflare Pages build
git push origin main
# Within ~2-3 minutes, your changes are live globally
Branch Deployments
Every non-main branch also gets a preview URL:
# Create a feature branch
git checkout -b feature/new-section
# Make changes and push
git push origin feature/new-section
# Preview URL is automatically created:
# https://<commit-hash>.my-docs.pages.dev
# or
# https://feature-new-section.my-docs.pages.dev
Troubleshooting Common Build Failures
Error: Cannot find module 'X'
# Cause: Dependencies not in package.json
# Fix: ensure devDependencies are committed
npm install some-package
git add package.json package-lock.json
git commit -m "fix: add missing dependency"
git push
Build timeout (20 minutes exceeded)
# Cause: Too many pages, very large build
# Fix 1: Increase Node.js memory
# In Environment Variables:
NODE_OPTIONS=--max-old-space-size=4096
# Fix 2: Disable some slow plugins during CI
# In docusaurus.config.js:
process.env.CF_PAGES && /* disable plugin */
Error: baseUrl mismatch
// Wrong (causes 404 on assets)
baseUrl: '/my-docs/',
// Correct for root deployment
baseUrl: '/',
Build succeeds but site shows 404
# Check your build output directory
# Docusaurus outputs to: build/
# NOT: dist/, public/, out/
# In Cloudflare Pages dashboard:
# Build output directory: build (no leading slash)
Post-Migration Checklist
After successful deployment, verify:
- Site loads at
your-project.pages.dev - Custom domain resolves and shows valid HTTPS
- All internal links work (no broken navigation)
- Search works (if using Algolia or Docusaurus search)
- Images and assets load correctly
- Sitemap is accessible at
/sitemap.xml -
git pushtriggers a new build automatically
Key Takeaways
- The migration from self-hosted Docker Docusaurus → GitHub + Cloudflare Pages takes under 30 minutes.
- The workflow is:
git push→ automatic build → global edge deployment. - Cloudflare Pages handles SSL, CDN, DDoS protection, and preview deployments for free.
- Custom domains are configured with a single CNAME record and SSL is automatic.
What's Next
- Continue to Wrangler CLI — Complete Reference to master the command-line interface for Cloudflare Pages.