This guide walks through deploying the Threat Intelligence Dashboard to Cloudflare Workers with all required services.
- GitHub account
- Cloudflare account (free tier works!)
- Node.js 18+ installed
- Git installed
Note: Analytics Engine will need to be enabled on first deployment (one-time, account-level setup). Unlike D1/Vectorize/KV which are created per-project via CLI, Analytics Engine is an account capability enabled via dashboard.
npx wrangler loginThis opens your browser to authenticate. Once complete, you're ready to create resources.
Run these commands one at a time and save the IDs from each:
D1 Database:
npx wrangler d1 create threat-intel-dbOutput will include:
database_id = "abc123..."
Save this ID!
Vectorize Index:
npx wrangler vectorize create threat-embeddings --dimensions=1024 --metric=cosineNote: We use 1024 dimensions because the BGE-Large embedding model outputs 1024-dim vectors.
KV Namespaces:
npx wrangler kv namespace create CACHE
npx wrangler kv namespace create CACHE --previewOutput will include two IDs:
- Production:
id = "xyz789..." - Preview:
preview_id = "def456..."
Save both IDs!
AI Gateway provides intelligent caching, real-time observability, and rate limiting for Workers AI requests.
Create via Cloudflare Dashboard:
- Go to Cloudflare Dashboard → AI → AI Gateway
- Click "Create Gateway"
- Name:
threat-intel-dashboard - Click "Create"
- Copy the Gateway ID (you'll need this in Step 4)
Benefits:
- ✅ 30-40% neuron savings through intelligent caching of duplicate AI requests
- ✅ Real-time analytics dashboard with request logs, latency metrics, and error tracking
- ✅ Rate limiting to protect against quota exhaustion
- ✅ Cache hit rates showing how often identical requests are served from cache
- ✅ Model usage breakdown across Llama 1B, Qwen 30B, and BGE-M3
Note: AI Gateway is required for this project and must be created before deployment.
Edit wrangler.jsonc and replace these values:
Commit your changes:
git add wrangler.jsonc
git commit -m "Configure production resource IDs"
git push origin mainnpx wrangler d1 execute threat-intel-db --remote --file=./schema.sqlThis creates:
- 8 tables (threats, summaries, iocs, categories, etc.)
- Default categories (ransomware, apt, vulnerability, etc.)
- 7 security feed sources (CISA, Krebs, BleepingComputer, etc.)
You should see: ✅ Executed 24 queries (or similar)
GitHub Actions will automatically deploy your Worker when you push to main.
Required GitHub Secrets:
-
CLOUDFLARE_API_TOKEN
- Go to https://dash.cloudflare.com/profile/api-tokens
- Create token with "Edit Cloudflare Workers" template
- Copy the token
-
CLOUDFLARE_ACCOUNT_ID
- Go to https://dash.cloudflare.com/
- Copy your Account ID from the sidebar
Add to GitHub:
- Go to your repo → Settings → Secrets and variables → Actions
- Add
CLOUDFLARE_API_TOKENsecret - Add
CLOUDFLARE_ACCOUNT_IDsecret
See GitHub CI/CD Setup Guide for detailed instructions.
Option A: Deploy via GitHub Actions (Recommended)
git push origin mainGitHub Actions will automatically:
- Build the frontend
- Compile Pages Functions to
_worker.js - Deploy to Cloudflare Workers
Option B: Deploy Manually
npm run deployThis builds and deploys directly from your local machine.
This is expected! On your first deployment, you may see:
Error: You need to enable Analytics Engine. Head to the Cloudflare Dashboard to enable
[code: 10089]
This is normal - Analytics Engine is an account-level feature that requires one-time enablement:
- Go to Dashboard → Workers & Pages → Analytics Engine
- Click "Enable Analytics Engine" (one-time setup for your entire account)
- Re-deploy (push to GitHub or run
npm run deploy) - Note: The dataset (
threat_metrics) auto-creates on first use - you don't manually create it
Why this happens:
- Analytics Engine is an account capability (like enabling Workers AI), not a per-project resource
- No CLI command exists to enable it - must be done via dashboard
- Once enabled, all your projects can use Analytics Engine (never need to enable again)
- Datasets auto-create when your Worker first calls
writeDataPoint()
Comparison:
- D1/Vectorize/KV: Per-project resources → Created via CLI commands
- Analytics Engine: Account feature → Enabled once via dashboard, datasets auto-create
The Worker will automatically fetch and process threat data!
- Cron schedule: Every 6 hours (00:00, 06:00, 12:00, 18:00 UTC)
- First run: Happens within 6 hours of deployment
- No manual intervention needed!
Monitor the cron execution:
npx wrangler tailYou'll see logs like:
[Cron] Scheduled event triggered: 0 */6 * * *
Starting scheduled feed ingestion...
Processed Krebs on Security: 15 articles (3 new)
Ingestion complete. New threats: 42
Note: Debug endpoints (/api/debug/*) are disabled in production for security. The cron trigger handles all data ingestion automatically.
Your dashboard is now:
- ✅ Live on Cloudflare Workers
- ✅ Auto-updating every 6 hours via native cron triggers
- ✅ Processing threats with AI
- ✅ 100% serverless and free tier compatible
Visit: https://threat-intel-dashboard.YOUR-SUBDOMAIN.workers.dev
Or set up a custom domain in the Cloudflare dashboard.
After deployment, monitor your AI Gateway for caching effectiveness and usage patterns:
Access AI Gateway Dashboard:
- Go to Cloudflare Dashboard → AI → AI Gateway
- Select
threat-intel-dashboard - View the Analytics tab
Key Metrics to Monitor:
- Request count: Total AI requests processed
- Cache hit rate: Percentage of requests served from cache (target: 30-40%)
- Model usage breakdown: Distribution across Llama 1B, Qwen 30B, BGE-M3
- Latency metrics: Response times for AI requests
- Error rates: Failed AI requests
Expected Behavior:
- First run: 0% cache hit rate (all requests are new)
- Subsequent runs: 30-40% cache hit rate as duplicate content is analyzed
- Model distribution: ~60% Llama 1B, ~35% Qwen 30B, ~5% embeddings
Cost Savings: AI Gateway caching reduces neuron consumption by 30-40%, saving ~1,000-1,500 neurons per day.
If you encounter issues, you can monitor production logs in real-time:
CLI Method (Recommended):
npx wrangler tailWeb UI Method:
- Go to Workers & Pages
- Select your Worker (
threat-intel-dashboard) - Click the "Logs" tab
- Click "Begin log stream"
Both methods provide equivalent output. Trigger an action and watch for errors in real-time.
For local development:
npm run devThis starts Wrangler dev server at http://localhost:8787 with local bindings.
Cloudflare Dashboard:
- Go to Workers & Pages → threat-intel-dashboard
- Click "Triggers" tab
- View cron execution history
CLI:
npx wrangler tail
# Wait for next cron execution (00:00, 06:00, 12:00, or 18:00 UTC)To change the ingestion frequency, edit wrangler.jsonc:
"triggers": {
"crons": ["0 */6 * * *"] // Every 6 hours (current)
// "crons": ["0 */3 * * *"] // Every 3 hours
// "crons": ["0 * * * *"] // Every hour (uses more quota)
}Re-deploy after changes:
git add wrangler.jsonc
git commit -m "Update cron schedule"
git push origin mainNote: The free tier includes 5 cron triggers. See Cloudflare Workers cron syntax for more options.
Production security posture:
- ✅ Management endpoints disabled (HTTP 403)
- ✅ Cron triggers run internally (not exposed to internet)
- ✅ Public API endpoints are read-only
- ✅ Rate limiting protects against abuse
- ✅ Security headers on all responses
See Security Documentation for details.
- GitHub CI/CD Setup - Configure automatic deployment
- Project Structure - Understand the codebase
- Security Documentation - Security features and implementation
- Cloudflare Workers Docs
- Workers Cron Triggers
Need help? Check the Cloudflare Discord or Community Forum
{ "d1_databases": [ { "database_id": "YOUR_D1_DATABASE_ID" // ← Paste your D1 ID here } ], "vectorize": [ { "index_name": "threat-embeddings", "binding": "VECTORIZE_INDEX" } ], "kv_namespaces": [ { "id": "YOUR_KV_NAMESPACE_ID", // ← Paste production KV ID "preview_id": "YOUR_KV_PREVIEW_ID" // ← Paste preview KV ID } ], "vars": { "ENVIRONMENT": "production", "AI_GATEWAY_ID": "threat-intel-dashboard" // ← AI Gateway ID from Step 3 } }