DocsBlogDocsBlog
Log in

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

  1. Sign up at https://dash.cloudflare.com/sign-up (free tier works)
  2. After registration, go to the Cloudflare Dashboard
  3. Note your Account ID (visible on the dashboard home page or the Workers & Pages section)

2. Create an API Token

  1. Go to https://dash.cloudflare.com/profile/api-tokens
  2. Click Create Token
  3. Select the Edit Cloudflare Workers template
  4. Confirm permissions include: Account - Workers Scripts - Edit, Account - Workers KV Storage - Edit
  5. Click Continue to summaryCreate Token
  6. 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 whoami

4. 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 production

Each 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_ADMIN to "false" in production. ADMIN_API_KEY and DEEPSEEK_API_KEY are only needed in your local .env file — 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 production

Build pipeline:

  1. pnpm run aggregate — aggregate content data
  2. next build — Next.js production build
  3. opennextjs-cloudflare build — package as Worker
  4. wrangler 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

  1. Go to Cloudflare Dashboard → Workers & Pages
  2. Click your Worker
  3. Go to Settings → Domains & Routes
  4. Click Add Domain and enter your domain
  5. 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 Cloudflare

Setup

Step 1: Add Repository Secrets

Go to your GitHub repo → Settings → Secrets and variables → Actions → New repository secret:

Secret NameValueDescription
CLOUDFLARE_API_TOKENCloudflare API TokenCreated in step 2 above
CLOUDFLARE_ACCOUNT_IDCloudflare Account IDFrom 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 main

Once pushed to main, GitHub Actions automatically:

  1. Installs dependencies (pnpm install --frozen-lockfile)
  2. Builds the Worker (opennextjs-cloudflare build)
  3. Deploys to Cloudflare production (wrangler deploy --env production)
  4. 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 tests
  • pnpm 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

  1. Verify the KV namespace ID in wrangler.jsonc is correct
  2. Confirm open-next.config.ts cache config is intact
  3. First page visit returns MISS — this is normal. Second visit should return HIT

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