Skip to main content
Cloudflare

Cloudflare Workers Deployment Guide: From Local Development to Production

By JunZhi Blog Team27 min read
Cloudflare Workers Deployment Guide: From Local Development to Production

Cloudflare Workers Deployment Guide: From Local Development to Production

Cloudflare Workers and Cloudflare Pages make it possible to run applications close to users around the world. For content websites and lightweight apps, this can deliver fast global performance without managing servers.

This guide walks through a practical deployment workflow: Wrangler setup, project configuration, Next.js static export, environment variables, D1 bindings, caching, security headers, and production verification.

1. Why deploy on Cloudflare?

Cloudflare is useful for modern web projects because it provides:

  • Global edge network delivery.
  • Low-latency request handling.
  • No traditional server maintenance.
  • Built-in CDN and caching.
  • D1, KV, R2, Queues, and Workers AI integrations.
  • Strong DNS, SSL, and security tooling.

For a technical blog or content product, the ideal pattern is static pages for public reading and Workers or Pages Functions for dynamic features.

2. Install Wrangler

Wrangler is the official Cloudflare CLI.

npm install --save-dev wrangler
npx wrangler --version

Log in when working locally:

npx wrangler login

For CI deployments, use CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID as secrets instead of browser login.

3. Configure a static Next.js export

For a content site that can be statically generated, configure Next.js for static export:

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  output: 'export',
  images: {
    unoptimized: true,
  },
}

export default nextConfig

Static export is a strong choice for public articles because it makes pages fast, cacheable, and resilient.

4. Add a Pages configuration

Example wrangler.toml:

name = "my-site"
pages_build_output_dir = "./out"
compatibility_date = "2026-05-01"

[[d1_databases]]
binding = "DB"
database_name = "my-site-db"
database_id = "your-database-id"

[vars]
NODE_ENV = "production"

The pages_build_output_dir should match the output folder produced by next build when using static export.

5. Build and deploy

Use scripts like:

{
  "scripts": {
    "build": "next build",
    "deploy": "npm run build && wrangler pages deploy out --project-name=my-site"
  }
}

Then deploy:

npm run deploy

For CI, run checks before deployment:

npm ci
npm audit --audit-level=high
npm run lint
npm run typecheck
npm run build
npx wrangler pages deploy out --project-name=my-site

6. Use Pages Functions for APIs

Cloudflare Pages can serve static assets and run Functions from the functions directory.

Example:

export const onRequestGet: PagesFunction<Env> = async (context) => {
  const posts = await context.env.DB.prepare(
    'SELECT slug, title FROM posts WHERE published = 1 ORDER BY created_at DESC'
  ).all()

  return Response.json({
    success: true,
    data: posts.results,
  })
}

This lets a mostly static site still support admin features, comments, counters, and dynamic APIs.

7. Bind D1 carefully

D1 works well for small content platforms, but the binding must be available in production and local development.

Check:

  • binding name matches the code.
  • database_id is correct.
  • migrations have been applied.
  • production and preview environments use the intended database.
  • private data is not exposed by public APIs.

Use static pages for high-traffic content and D1 for lower-frequency dynamic features.

8. Configure security headers

Cloudflare Pages supports a _headers file. A baseline might include:

/*
  X-Content-Type-Options: nosniff
  X-Frame-Options: DENY
  Referrer-Policy: strict-origin-when-cross-origin
  Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()

/admin/*
  X-Robots-Tag: noindex, nofollow, noarchive

/auth/*
  X-Robots-Tag: noindex, nofollow, noarchive

Security headers improve both user safety and search-engine clarity.

9. Cache public pages, protect private APIs

Public pages can use aggressive CDN caching when generated statically. Private APIs should be more careful.

Recommended behavior:

  • Cache public assets and static pages.
  • Do not publicly cache authenticated API responses.
  • Add Vary: Origin when using Origin-specific CORS.
  • Keep admin routes behind authentication.
  • Avoid exposing draft or user-only content in the sitemap.

10. Verify after deployment

After every production deployment, check:

curl -I https://example.com
curl -I https://example.com/sitemap.xml
curl -I https://example.com/admin

Confirm:

  • Homepage returns 200.
  • Sitemap is reachable.
  • Private pages are noindex.
  • Security headers are present.
  • Images load correctly.
  • Important article pages render.
  • API responses do not expose sensitive details.

Conclusion

Cloudflare Workers and Pages are excellent for fast global websites when the architecture is simple and intentional. Serve public articles as static pages, use Functions for dynamic features, bind D1 carefully, keep private routes out of search results, and verify production responses after deployment.

This setup gives content sites a strong mix of speed, low operational cost, and practical scalability.

Comments

Share your thoughts and join the discussion

Login required to comment0 / 1000

Please or to comment

Comments (0)

Related Articles