Cloudflare Setup
Configure Cloudflare R2, KV, and Workers for self-hosted Scry.
Prerequisites
- Cloudflare account
- Wrangler CLI installed and authenticated
# Verify Wrangler is set up
wrangler whoamiR2 Storage Setup
Create Buckets
Create separate buckets for production and staging:
# Production bucket
wrangler r2 bucket create scry-static-sites
# Staging bucket
wrangler r2 bucket create scry-static-sites-stagingEnable Public Access
For the CDN to serve files publicly:
- Go to Cloudflare Dashboard → R2
- Select your production bucket
- Go to Settings tab
- Find Public access section
- Click Allow Access
- Confirm
Note the public URL: https://pub-{bucket-hash}.{account-id}.r2.dev
Create API Token
For S3-compatible API access:
- Go to R2 → Manage R2 API Tokens
- Click Create API Token
- Configure:
- Token name: Scry Upload Service
- Permissions: Object Read & Write
- Specify bucket(s): Select your buckets
- Create token
- Copy both values immediately:
- Access Key ID
- Secret Access Key
Verify R2 Access
# Test with AWS CLI (using R2 endpoint)
aws s3 ls s3://scry-static-sites \
--endpoint-url https://{account-id}.r2.cloudflarestorage.comKV Namespace Setup
Create Namespaces
# Production namespace
wrangler kv:namespace create CDN_CACHEOutput:
🌀 Creating namespace with title "scry-cdn-service-CDN_CACHE"
✨ Success!
Add the following to your configuration file:
[[kv_namespaces]]
binding = "CDN_CACHE"
id = "abc123..."# Preview namespace (for local development)
wrangler kv:namespace create CDN_CACHE --previewNote both IDs for your configuration.
Configure in wrangler.toml
[[kv_namespaces]]
binding = "CDN_CACHE"
id = "your-production-id"
preview_id = "your-preview-id"Workers Deployment
Upload Service
See Upload Service Deployment for detailed steps.
Quick overview:
# Clone and install
git clone https://github.com/epinnock/scry-storybook-upload-service.git
cd scry-storybook-upload-service
npm install
# Configure wrangler.toml
# Set secrets
wrangler secret put R2_ACCOUNT_ID
wrangler secret put R2_S3_ACCESS_KEY_ID
wrangler secret put R2_S3_SECRET_ACCESS_KEY
# Deploy
npm run build && wrangler deployCDN Service
See CDN Service Deployment for detailed steps.
Quick overview:
# Clone and install
git clone https://github.com/epinnock/scry-cdn-service.git
cd scry-cdn-service
npm install
# Configure wrangler.toml with KV namespace
# Deploy
npm run build:cloudflare && wrangler deployCustom Domain Setup
Add Domain to Cloudflare
If not already using Cloudflare for DNS:
- Go to Cloudflare Dashboard
- Click Add a Site
- Enter your domain
- Select a plan (Free works)
- Update nameservers at your registrar
Configure DNS for CDN
Add a wildcard record for subdomain routing:
Option 1: AAAA Record (Recommended)
| Type | Name | Content | Proxy |
|---|---|---|---|
| AAAA | view-* | 100:: | Proxied |
Option 2: CNAME Record
| Type | Name | Content | Proxy |
|---|---|---|---|
| CNAME | * | your-cdn-worker.workers.dev | Proxied |
Configure Worker Routes
Update CDN Service wrangler.toml:
routes = [
{ pattern = "view-*.yourdomain.com/*", zone_name = "yourdomain.com" }
]Redeploy:
wrangler deployConfigure Custom Domain for Upload Service
Option 1: Use Workers subdomain (default)
Option 2: Add custom domain:
- Go to Workers → Your Worker → Triggers
- Click Add Custom Domain
- Enter
api.yourdomain.com - Add route
SSL/TLS Configuration
Cloudflare handles SSL automatically when proxy is enabled.
For optimal security:
- Go to SSL/TLS → Overview
- Select Full (strict) mode
- Enable Always Use HTTPS
Security Settings
Configure WAF Rules (Optional)
- Go to Security → WAF
- Create custom rules for rate limiting:
(http.request.uri.path contains "/upload" and rate > 100)Configure Access Policies (Optional)
Restrict dashboard access to specific users:
- Go to Access → Applications
- Create application for dashboard
- Configure policies
Verification
Test R2 Access
# Upload test file
echo "test" > test.txt
wrangler r2 object put scry-static-sites/test.txt --file=test.txt
# Verify public access
curl https://pub-xxx.r2.dev/test.txtTest KV Access
# Write test value
wrangler kv:key put --namespace-id=xxx test-key "test-value"
# Read test value
wrangler kv:key get --namespace-id=xxx test-keyTest Worker Health
# Upload Service
curl https://your-upload-service.workers.dev/health
# CDN Service
curl -H "Host: view-test.yourdomain.com" https://your-cdn-service.workers.dev/healthCost Monitoring
Set up billing alerts:
- Go to your Cloudflare dashboard
- Navigate to Manage Account → Billing
- Set up notifications for usage thresholds
Current Pricing (as of 2024)
| Resource | Free Tier | Paid |
|---|---|---|
| Workers Requests | 100K/day | $0.50/M |
| R2 Storage | 10 GB | $0.015/GB |
| R2 Operations | 10M Class A, 1M Class B | $0.36/M, $0.036/M |
| KV Reads | 100K/day | $0.50/M |
| KV Writes | 1K/day | $5.00/M |
Troubleshooting
"R2 bucket not found"
- Verify bucket name in wrangler.toml
- Check bucket exists:
wrangler r2 bucket list
"KV namespace not found"
- Verify namespace ID in wrangler.toml
- Check namespace exists:
wrangler kv:namespace list
"Route not matching"
- Verify DNS is proxied (orange cloud)
- Check zone_name matches your domain
- Verify pattern matches expected URLs
"Public URL returns 403"
- Enable public access on R2 bucket
- Wait a few minutes for propagation
Next Steps
- Firebase Setup - Configure authentication
- Complete Setup - Full deployment guide