Agent Skills: Deploying Cloudflare Workers

|

UncategorizedID: stakpak/community-paks/cloudflare-workers

Install this agent skill to your local

pnpm dlx add-skill https://github.com/stakpak/community-paks/tree/HEAD/cloudflare-workers

Skill Files

Browse the full folder contents for cloudflare-workers.

Download Skill

Loading file tree…

cloudflare-workers/SKILL.md

Skill Metadata

Name
cloudflare-workers
Description
|

Deploying Cloudflare Workers

Quick Start

Create and Deploy

# Create project
npm create cloudflare@latest my-worker -- --type=hello-world --ts=false --git=false --deploy=false
cd my-worker

# Deploy
export CLOUDFLARE_API_TOKEN="your-token-here"
export CLOUDFLARE_ACCOUNT_ID="your-account-id"
npx wrangler deploy

Prerequisites

  • Node.js 16.17.0 or later installed
  • Cloudflare account (free tier works)
  • Cloudflare API token with Workers permissions

Setup

1. Create API Token

Before deployment, create a Cloudflare API token with proper permissions:

  1. Go to https://dash.cloudflare.com/profile/api-tokens
  2. Click "Create Token"
  3. Select "Edit Cloudflare Workers" template
  4. Click "Continue to summary""Create Token"
  5. Save the token securely

Required permissions:

  • Account: Workers Scripts (Edit)
  • Account: Account Settings (Read)
  • User: User Details (Read)

2. Register workers.dev Subdomain

If this is your first Worker deployment:

  1. Go to Cloudflare Dashboard → Workers & Pages
  2. Look for "Your subdomain" section
  3. Click "Change" or "Set up"
  4. Enter a unique subdomain name (e.g., mycompany)
  5. Save

Your workers will be available at: <worker-name>.<subdomain>.workers.dev

3. Create Worker Project

Use C3 (create-cloudflare-cli) to scaffold the project:

npm create cloudflare@latest my-worker -- --type=hello-world --ts=false --git=false --deploy=false
cd my-worker

Generated structure:

my-worker/
├── src/
│   └── index.js      # Worker entry point
├── wrangler.jsonc    # Wrangler configuration
├── package.json
└── node_modules/

4. Configure Wrangler

Update wrangler.jsonc with your worker settings:

{
  "$schema": "./node_modules/wrangler/config-schema.json",
  "name": "my-worker",
  "main": "src/index.js",
  "compatibility_date": "2024-12-01",
  "observability": {
    "enabled": true
  }
}

Key settings:

  • name: Worker name (becomes part of URL)
  • main: Entry point file
  • compatibility_date: Runtime compatibility version
  • observability: Enable logging and metrics

5. Implement the Worker Handler

Workers use a fetch handler pattern. Create your worker logic in src/index.js:

/**
 * Worker Handler Template
 * Handles routing, JSON responses, and CORS
 */

export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);
    const path = url.pathname;

    // CORS headers for all responses
    const corsHeaders = {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
      'Access-Control-Allow-Headers': 'Content-Type',
    };

    // Handle OPTIONS preflight
    if (request.method === 'OPTIONS') {
      return new Response(null, { headers: corsHeaders });
    }

    // Route handling
    switch (path) {
      case '/health':
        return jsonResponse({
          status: 'healthy',
          service: 'my-worker',
          timestamp: new Date().toISOString()
        }, 200, corsHeaders);
      
      case '/api/endpoint':
        return handleApiEndpoint(request, url, corsHeaders);
      
      default:
        return jsonResponse({
          error: 'Not found',
          available_endpoints: ['GET /health', 'GET /api/endpoint']
        }, 404, corsHeaders);
    }
  },
};

function handleApiEndpoint(request, url, corsHeaders) {
  // Parse query parameters
  const params = url.searchParams;
  const param1 = params.get('param1');
  
  // Validate
  if (!param1) {
    return jsonResponse({
      error: 'Missing required parameter: param1'
    }, 400, corsHeaders);
  }
  
  // Process and return
  return jsonResponse({
    result: `Processed: ${param1}`
  }, 200, corsHeaders);
}

function jsonResponse(data, status = 200, additionalHeaders = {}) {
  return new Response(JSON.stringify(data, null, 2), {
    status: status,
    headers: {
      'Content-Type': 'application/json',
      ...additionalHeaders
    }
  });
}

Handler parameters:

  • request: Incoming HTTP Request object
  • env: Environment bindings (KV, D1, secrets, etc.)
  • ctx: Execution context (waitUntil, passThroughOnException)

6. Test Locally

Run the development server:

npx wrangler dev

Test the worker at http://localhost:8787:

curl http://localhost:8787/health
curl "http://localhost:8787/api/endpoint?param1=test"

7. Deploy to Production

Deploy using environment variables for authentication:

export CLOUDFLARE_API_TOKEN="your-token-here"
export CLOUDFLARE_ACCOUNT_ID="your-account-id"
npx wrangler deploy

Finding your Account ID:

  • Dashboard → Workers & Pages → Account ID in sidebar
  • Or from the URL: dash.cloudflare.com/<account-id>/workers

8. Verify Deployment

Test the live worker:

# Health check
curl https://my-worker.mysubdomain.workers.dev/health

# API endpoint
curl "https://my-worker.mysubdomain.workers.dev/api/endpoint?param1=test"

Common Patterns

Request Method Handling

switch (request.method) {
  case 'GET':
    return handleGet(url);
  case 'POST':
    const body = await request.json();
    return handlePost(body);
  case 'PUT':
    return handlePut(request);
  case 'DELETE':
    return handleDelete(url);
  default:
    return jsonResponse({ error: 'Method not allowed' }, 405);
}

Path Parameter Extraction

// For paths like /users/123
const match = path.match(/^\/users\/(\d+)$/);
if (match) {
  const userId = match[1];
  return handleUser(userId);
}

Environment Variables and Secrets

Add to wrangler.jsonc:

{
  "vars": {
    "API_VERSION": "v1"
  }
}

Add secrets via CLI:

npx wrangler secret put API_KEY

Access in handler:

async fetch(request, env, ctx) {
  const version = env.API_VERSION;
  const apiKey = env.API_KEY;
}

KV Storage Binding

Add to wrangler.jsonc:

{
  "kv_namespaces": [
    { "binding": "CACHE", "id": "your-kv-namespace-id" }
  ]
}

Use in handler:

// Read
const value = await env.CACHE.get('key');

// Write
await env.CACHE.put('key', 'value', { expirationTtl: 3600 });

Deployment Options

| Method | Use Case | |--------|----------| | workers.dev subdomain | Quick testing, hobby projects | | Custom Domain | Production deployments | | Routes | Add Workers to existing domains |

Custom Domain Setup

Add to wrangler.jsonc:

{
  "routes": [
    { "pattern": "api.example.com/*", "custom_domain": true }
  ]
}

Troubleshooting

| Issue | Solution | |-------|----------| | Authentication error | Verify API token has correct permissions, check CLOUDFLARE_ACCOUNT_ID is set correctly, ensure token hasn't expired | | workers.dev subdomain not registered | Go to Dashboard → Workers & Pages → Set up subdomain (must be done before first deployment) | | SSL handshake failures | New deployments may take 1-2 minutes for SSL provisioning, try accessing via browser first, check with curl --insecure to bypass local SSL issues | | Worker not updating | Clear browser cache, check deployment version ID in output, use wrangler tail to see live logs |

References