Deploy docsblog-app to Cloudflare Workers with manual and automated GitHub Actions deployment
Deployment Guide
This template runs on Cloudflare Workers using the opennextjs-cloudflare adapter, with ISR incremental static regeneration and KV caching.
1. Create a Cloudflare Account
- Sign up at https://dash.cloudflare.com/sign-up (free tier works)
- After registration, go to the Cloudflare Dashboard
- Note your Account ID (visible on the dashboard home page or the Workers & Pages section)
2. Create an API Token
- Go to https://dash.cloudflare.com/profile/api-tokens
- Click Create Token
- Select the Edit Cloudflare Workers template
- Confirm permissions include:
Account - Workers Scripts - Edit,Account - Workers KV Storage - Edit - Click Continue to summary → Create Token
- Copy the generated token (shown only once — save it securely)
3. Install Wrangler & Login
Wrangler CLI is bundled with the project via @opennextjs/cloudflare. No global install needed.
# Login to Cloudflare (opens browser for authorization)
npx wrangler login
# Verify login
npx wrangler whoami4. Create KV Namespaces
The app uses Cloudflare KV for page caching (ISR).
# Create dev KV namespace
npx wrangler kv namespace create NEXT_INC_CACHE_KV
# Create production KV namespace
npx wrangler kv namespace create NEXT_INC_CACHE_KV --env productionEach command outputs an id. Note both the dev and production IDs.
5. Configure wrangler.jsonc
Open wrangler.jsonc and fill in the KV IDs and production domain:
{
// Dev environment KV
"kv_namespaces": [
{
"binding": "NEXT_INC_CACHE_KV",
"id": "<your-dev-kv-namespace-id>"
}
],
"env": {
"production": {
"vars": {
"NEXT_PUBLIC_SITE_URL": "https://your-domain.com",
"NEXT_PUBLIC_BASE_URL": "https://your-domain.com",
"ENABLE_ADMIN": "false"
},
"kv_namespaces": [
{
"binding": "NEXT_INC_CACHE_KV",
"id": "<your-prod-kv-namespace-id>"
}
]
}
}
}Note: The admin panel is for local development only. Set
ENABLE_ADMINto"false"in production.ADMIN_API_KEYandDEEPSEEK_API_KEYare only needed in your local.envfile — do not deploy them to production.
6. Manual Deployment
Build & Deploy Locally
# One-command build + deploy (dev environment)
pnpm run deploy:cf
# Deploy to production
pnpm exec opennextjs-cloudflare build && npx wrangler deploy --env productionBuild pipeline:
pnpm run aggregate— aggregate content datanext build— Next.js production buildopennextjs-cloudflare build— package as Workerwrangler deploy— deploy to Cloudflare
Verify Deployment
# Check page cache status
curl -sI https://your-domain.com | grep x-nextjs-cache
# Expected output:
# x-nextjs-cache: HIT (served from cache)
# x-nextjs-cache: MISS (first visit, will be HIT on next request)
# x-nextjs-cache: STALE (serving stale while revalidating in background)8. Custom Domain
- Go to Cloudflare Dashboard → Workers & Pages
- Click your Worker
- Go to Settings → Domains & Routes
- Click Add Domain and enter your domain
- Cloudflare automatically configures DNS
Worker Custom Domains bypass the CDN cache layer. Dashboard Cache Rules have no effect on Workers. Caching is handled entirely by the Worker's internal KV mechanism.
9. GitHub Actions Auto-Deploy
The project includes .github/workflows/deploy.yml for automatic deployment when pushing to the main branch.
How It Works
Feature branch → Commit → Merge to main → GitHub Actions triggers → Build → Deploy to CloudflareSetup
Step 1: Add Repository Secrets
Go to your GitHub repo → Settings → Secrets and variables → Actions → New repository secret:
| Secret Name | Value | Description |
|---|---|---|
CLOUDFLARE_API_TOKEN | Cloudflare API Token | Created in step 2 above |
CLOUDFLARE_ACCOUNT_ID | Cloudflare Account ID | From your dashboard |
The admin panel and AI translation are for local development only.
ADMIN_API_KEY,DEEPSEEK_API_KEY, etc. do not need to be added as GitHub Secrets.
Step 2: Create Environment
Go to Settings → Environments, create an environment named CLOUDFLARE-DocsBlog-Prod (matches the environment field in deploy.yml).
Step 3: Push to main to Trigger Deploy
# Develop on a feature branch
git checkout -b feature/my-change
# ... make changes ...
git add .
git commit -m "feat: my new feature"
# Push to remote
git push origin feature/my-change
# Create a Pull Request on GitHub → Review → Merge to main
# Or push directly to main (for personal projects)
git checkout main
git merge feature/my-change
git push origin mainOnce pushed to main, GitHub Actions automatically:
- Installs dependencies (
pnpm install --frozen-lockfile) - Builds the Worker (
opennextjs-cloudflare build) - Deploys to Cloudflare production (
wrangler deploy --env production) - Syncs secrets to Worker environment variables
Step 4: Monitor Deployment
Go to your GitHub repo → Actions tab to view deployment status and logs for each run.
CI Checks
The project also includes .github/workflows/ci.yml, which runs on every push and PR:
pnpm run test— runs testspnpm run build— verifies build succeeds
Merge to main only after CI passes, then the deploy workflow takes over.
Troubleshooting
Build Fails: NEXT_PUBLIC_SITE_URL Not Set
The scripts/verify-site-url.mjs script validates this variable before build. Make sure it's set in wrangler.jsonc env.production.vars or in the GitHub Actions env block.
KV Cache Not Working
- Verify the KV namespace ID in
wrangler.jsoncis correct - Confirm
open-next.config.tscache config is intact - First page visit returns
MISS— this is normal. Second visit should returnHIT
Wrangler Login Issues
# Re-login
npx wrangler login
# Or use API Token directly (for CI environments)
export CLOUDFLARE_API_TOKEN=your-token
npx wrangler whoami