This guide will walk you through deploying your BugReplay to production. Since you're new to web development, I've included detailed explanations for each step.
Before you start, you'll need:
-
A Cloudflare account (free tier is sufficient)
- Sign up at https://dash.cloudflare.com/sign-up
- Verify your email address
-
Node.js installed (version 18 or higher)
- Download from https://nodejs.org/
- Verify installation:
node --version
-
Wrangler CLI (Cloudflare's deployment tool)
- Install with:
npm install -g wrangler - Verify installation:
wrangler --version
- Install with:
Open your terminal and run:
wrangler loginThis will open your browser. Click "Allow" to authorize Wrangler to access your Cloudflare account.
R2 is Cloudflare's object storage (similar to AWS S3, but with free egress).
wrangler r2 bucket create bugreplay-storageYou should see:
✅ Successfully created bucket 'bugreplay-storage'.
D1 is Cloudflare's SQL database.
wrangler d1 create bugreplay-dbCopy the database_id from the output. It will look like:
✅ Successfully created DB 'bugreplay-db'
database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"Important: Save this database_id — you'll need it in the next step.
Open worker/wrangler.toml and update the following values:
name = "bugreplay-worker"
main = "src/index.js"
compatibility_date = "2024-01-01"
[vars]
SITE_URL = "https://your-worker-url.workers.dev" # You'll get this after first deploy
R2_PUBLIC_URL = "https://pub-xxxxxxxxxxxxx.r2.dev" # You'll get this after setting up R2
# JWT_SECRET is set via wrangler secret (not stored in this file):
# wrangler secret put JWT_SECRET
# AUTH_PASSWORD is set via wrangler secret (not stored in this file):
# wrangler secret put AUTH_PASSWORD
[[r2_buckets]]
binding = "BUCKET"
bucket_name = "bugreplay-storage"
[[d1_databases]]
binding = "DB"
database_name = "bugreplay-db"
database_id = "your-database-id-here" # Replace with the ID from Step 2bdatabase_id: Paste the ID you copied from Step 2bSITE_URL: Leave as placeholder for now — you'll update after first deploymentR2_PUBLIC_URL: Leave as placeholder for now — you'll set this up later
Secrets are sensitive values that are encrypted and never stored in your code.
This is the password you'll use to login and upload recordings.
wrangler secret put AUTH_PASSWORDWhen prompted, enter your desired password (you won't see it as you type). Press Enter to confirm.
Choose a strong password — this protects your upload endpoint.
This is used to sign and verify authentication tokens.
wrangler secret put JWT_SECRETWhen prompted, enter a random string. You can generate one with:
# On Windows (PowerShell):
-join ((1..32) | ForEach-Object { '{0:x2}' -f (Get-Random -Max 256) })
# On Mac/Linux:
openssl rand -base64 32Copy the output and paste it when prompted.
The migration file already exists at worker/migrations/0001_create_sessions.sql. It creates the sessions table with columns for id, video_key, telem_key, created_at, browser, os, viewport, and url, plus an index on created_at.
Apply the migration to your database:
wrangler d1 migrations apply bugreplay-db --remoteYou should see:
🌀 Executing on bugreplay-db (your-database-id-here):
✅ Successfully applied 1 migration
Navigate to the worker directory and deploy:
cd worker
npm install
wrangler deployYou'll see output like:
✅ Successfully published your Worker to
https://bugreplay-worker-your-subdomain.workers.dev
Copy this URL — this is your SITE_URL.
Update wrangler.toml:
SITE_URL = "https://bugreplay-worker-your-subdomain.workers.dev"To make video files publicly accessible (so viewers can watch them), you need to enable R2 public access.
For a production setup, you can use a custom domain. For testing, Cloudflare provides a default public URL.
Check your R2 bucket settings in the Cloudflare dashboard:
- Go to https://dash.cloudflare.com
- Navigate to: R2 → Buckets → bugreplay-storage → Settings
- Look for "Public Access" and enable it if not already enabled
- Note the public URL pattern
Update wrangler.toml:
R2_PUBLIC_URL = "https://pub-xxxxxxxxxxxxx.r2.dev"Before loading the extension, verify your worker is running:
# Test the root endpoint (should return 404 or serve viewer)
curl https://bugreplay-worker-your-subdomain.workers.dev
# Test the login endpoint
curl -X POST https://bugreplay-worker-your-subdomain.workers.dev/api/auth/login \
-H "Content-Type: application/json" \
-d '{"password":"your-password-here"}'If successful, you'll get a JWT token in response:
{"token":"eyJhbGciOiJIUzI1NiIs..."}- Open Chrome or Edge
- Navigate to:
chrome://extensions/(oredge://extensions/) - Enable Developer mode (toggle in top-right)
- Click Load unpacked
- Select the
extensionfolder from your project
The extension icon should now appear in your browser toolbar.
The extension needs to know where your worker is deployed.
Create extension/background/config.local.js (this file is gitignored — never commit your real URL) with your worker URL:
self.BACKEND_URL = "https://YOUR-WORKER.workers.dev";service-worker.js loads this via importScripts('config.local.js') and falls back to a placeholder if missing.
Reload the extension:
- Go to
chrome://extensions/ - Click the refresh icon on your extension card
- Click the extension icon in your toolbar
- Get a JWT token — send a POST request to your login endpoint:
Copy the
curl -X POST https://bugreplay-worker-your-subdomain.workers.dev/api/auth/login \ -H "Content-Type: application/json" \ -d '{"password":"your-password-here"}'
tokenvalue from the response. - Click the settings gear icon (⚙️) in the extension popup
- Paste your JWT token into the JWT Token field and click "Save"
- Click "Start Recording" — the extension will begin capturing your screen
- Interact with your browser — visit some pages, click around
- Click "Stop Recording" — the extension will upload to your worker
- Copy the viewer URL that appears (it's automatically copied to clipboard)
- Open the viewer URL in a new tab — you should see the video with synced telemetry
Before sharing your deployment:
- Verify secrets are set — run
wrangler secret listto confirmJWT_SECRETandAUTH_PASSWORDexist - Set up a custom domain (optional, but recommended for production)
- Enable Cloudflare Access (optional, for additional protection)
- Configure rate limiting in Cloudflare dashboard (prevents abuse)
- Set up monitoring with Cloudflare Analytics
- Test upload size limits — Workers have a 100MB request limit by default
- Run
wrangler secret listto verifyJWT_SECRETis set - If missing, set it with:
wrangler secret put JWT_SECRET
- Verify
database_idin wrangler.toml matches your D1 database - Run
wrangler d1 listto see your databases
- Verify the bucket name in wrangler.toml is
bugreplay-storage - Run
wrangler r2 bucket listto see your buckets
- Check browser console (F12) for CORS errors
- Verify
BACKEND_URLinextension/background/service-worker.jsmatches your worker URL - Make sure your worker is deployed:
wrangler deployments list
- Verify R2 public access is enabled in Cloudflare dashboard
- Check that
R2_PUBLIC_URLin wrangler.toml is correct - Open browser Network tab (F12) to see if video URLs are accessible
Good news — Cloudflare's free tier is generous:
| Resource | Free Limit | Expected Usage |
|---|---|---|
| Workers Requests | 100,000/day | < 100/day (personal use) |
| Workers CPU Time | 10ms/day avg | < 1s/day (personal use) |
| R2 Storage | 10 GB | < 1 GB (personal use) |
| R2 Class A Operations | 1M/month | < 1K/month |
| R2 Class B Operations | 10M/month | < 10K/month |
| D1 Database | 5 GB stored | < 1 MB (personal use) |
| D1 Rows Read | 5M/day | < 100/day |
You likely won't exceed free limits for personal use.
After your initial deployment:
- Customize the viewer UI — Edit the embedded HTML/CSS/JS in
worker/src/index.js(VIEWER_HTML, VIEWER_CSS, VIEWER_JS constants) - Add your branding — Update icons and colors
- Set up monitoring — Enable Cloudflare Web Analytics
- Configure custom domain — Use your own domain instead of
*.workers.dev - Share with others — Send viewer links to test the public replay feature
- Cloudflare Workers Docs: https://developers.cloudflare.com/workers/
- Wrangler CLI Reference: https://developers.cloudflare.com/workers/wrangler/
- R2 Storage Docs: https://developers.cloudflare.com/r2/
- D1 Database Docs: https://developers.cloudflare.com/d1/
You're done! 🎉 Your BugReplay is now deployed and ready to record and share browser sessions.