Self-Hosting botfighter
botfighter runs entirely on Cloudflare's free tier: Workers, D1, KV, and Pages. No servers to manage. Estimated setup time: 20 minutes.
Prerequisites
- Cloudflare account (free tier works)
- Node.js 18+ installed
- Wrangler CLI:
npm install -g wrangler@4
Step 1 — Authenticate
wrangler loginStep 2 — Clone the repo
git clone https://github.com/JustaRsearchGuy/botfighter.git
cd botfighterStep 3 — Create D1 database
wrangler d1 create botfighter-dbCopy the database_id from the output. Open worker/wrangler.toml and replace the database_id value with it.
Step 4 — Create KV namespace
wrangler kv namespace create BOTFIGHTER_KVCopy the id from the output. In worker/wrangler.toml, replace the KV id value with it.
Step 5 — Run database migrations
cd worker
wrangler d1 migrations apply botfighter-db --local # test locally first
wrangler d1 migrations apply botfighter-db # apply to productionThis creates the following tables: sites, detections, hourly_stats, bot_rules, passkeys, magic_links, leaderboard_cache.
Step 6 — Set required secrets
# Token hashing salt — generate with: openssl rand -hex 32
printf "YOUR_RANDOM_32_CHAR_STRING" | wrangler secret put OWNER_SALT --name botfighter-worker
# Admin secret — used to gate passkey registration and admin API routes
printf "YOUR_ADMIN_SECRET" | wrangler secret put ADMIN_SECRET --name botfighter-workerKeep OWNER_SALT secret and never change it after launch — changing it invalidates all existing owner tokens.
Step 7 — Set optional secrets
# Resend — for magic link email login (get API key at resend.com, "Sending access" permission)
printf "re_YOUR_KEY" | wrangler secret put RESEND_API_KEY --name botfighter-worker
# Kit/ConvertKit — subscribe new registrants to your mailing list
printf "YOUR_KIT_KEY" | wrangler secret put KIT_API_SECRET --name botfighter-worker
printf "YOUR_FORM_ID" | wrangler secret put KIT_FORM_ID --name botfighter-worker
# Restrict dashboard CORS to your custom domain (optional)
printf "https://dash.yourdomain.com" | wrangler secret put DASHBOARD_ORIGIN --name botfighter-workerStep 8 — Deploy the Worker
cd worker # if not already there
npm install
wrangler deployNote the Worker URL (e.g. https://botfighter-worker.YOUR-SUBDOMAIN.workers.dev).
Step 9 — Deploy the dashboard
cd ../dashboard
npm install
VITE_API_URL=https://YOUR-WORKER-URL npm run build
wrangler pages deploy dist --project-name botfighter-dashboardStep 10 — Register your admin passkey
This gives you access to the admin dashboard (all sites, delete, etc.).
Open your deployed dashboard and click "Register a passkey (first-time setup)". Enter your ADMIN_SECRET, then complete Face ID / Touch ID enrollment.
Once registered you can sign in with the passkey button.
Step 11 — Register your first site
Go to the dashboard and click Get started free →, or register via the API:
curl -X POST https://YOUR-WORKER-URL/admin/register-public \
-H "Content-Type: application/json" \
-d '{"domain": "yourdomain.com", "email": "you@yourdomain.com"}'Response:
{
"site_id": "yourdomain-com",
"domain": "yourdomain.com",
"owner_token": "abc123...",
"snippet": "<script src=\"...\">"
}Save the owner_token — it is shown only once. You can use it as the Bearer token to access your site's dashboard, or use magic link login if you provided an email.
Step 12 — Add the snippet to your site
Paste before </body> on every page:
<script
src="https://YOUR-WORKER-URL/botfighter.js"
data-site="YOUR-SITE-ID"
data-api="https://YOUR-WORKER-URL"
data-honeypot="true">
</script>Step 13 — Verify
curl https://YOUR-WORKER-URL/health
# → {"ok":true,"version":"0.1.0"}Open the dashboard, sign in, and you should see your site listed.
Logging in as a public user
Users who registered with an email can sign in via magic link:
- Click Sign in with email → on the login screen
- Enter the email used during registration
- Click the link in the email → auto-logged into their site dashboard
The magic link expires in 15 minutes and is single-use. Sessions last 30 days.
Updating
git pull
cd worker && wrangler deploy
cd ../dashboard && npm run build && wrangler pages deploy distFree tier limits (Cloudflare)
| Resource | Free limit | Typical botfighter usage |
|---|---|---|
| Workers requests | 100,000/day | ~1 req per page view |
| D1 reads | 5M rows/day | Low — aggregates reduce reads |
| D1 writes | 100K rows/day | 1 per visit (capped per site) |
| KV reads | 100K/day | 2–3 per visit |
| KV writes | 1K/day | Sessions + rate limits |
| Pages | Unlimited | Dashboard only |
For sites with >100k daily visitors, consider a paid Workers plan or lower DAILY_DETECTION_CAP:
printf "5000" | wrangler secret put DAILY_DETECTION_CAP --name botfighter-worker