Production Deployment
Complete guide for deploying SonicJS to production on Cloudflare's global edge platform.
Overview
SonicJS runs on Cloudflare's global edge network, providing:
- Cloudflare Workers - Serverless runtime at 300+ edge locations
- D1 Database - SQLite-based distributed database at the edge
- R2 Object Storage - S3-compatible storage for media files
- KV Storage - Low-latency key-value storage for caching
- Zero cold starts - Instant response times globally
Architecture
┌─────────────────────────────────────────────────────────┐
│ Cloudflare Edge │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Workers │ │ D1 Database │ │ R2 Storage │ │
│ │ (Runtime) │──│ (SQLite) │ │ (Media) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │ │ │
│ └───────────── KV Cache ────────────┘ │
└─────────────────────────────────────────────────────────┘
Deployment Environments
SonicJS supports three environments:
| Environment | Database | R2 Bucket | Domain |
|---|---|---|---|
| Development | local D1 | dev bucket | localhost:8787 |
| Preview | shared D1 | preview bucket | preview.workers.dev |
| Production | prod D1 | prod bucket | yourdomain.com |
Prerequisites
Required Accounts
-
Cloudflare Account
- Sign up at dash.cloudflare.com/sign-up
- Workers Paid plan ($5/month minimum)
- Payment method on file
-
Domain Name (optional but recommended)
- Can use
workers.devsubdomain for testing - Custom domain recommended for production
- Can use
Required Tools
Install the necessary tools:
Install Tools
# Verify Node.js 18+ is installed
node --version # Should be v18.0.0 or higher
npm --version
Login to Cloudflare
Authenticate with your Cloudflare account:
# Login to Cloudflare
wrangler login
# This will:
# 1. Open browser for authentication
# 2. Save credentials locally
# 3. Verify account access
# Verify login
wrangler whoami
Database Setup
Create Production Database
Create a new D1 database for production:
Create Database
# Create a new D1 database
wrangler d1 create sonicjs-ai
# Output example:
# ✅ Successfully created DB 'sonicjs-ai'
#
# [[d1_databases]]
# binding = "DB"
# database_name = "sonicjs-ai"
# database_id = "583c089c-1a4a-477d-9d58-06c07bf7c1d7"
Apply Database Migrations
Apply all database migrations to production:
Run Migrations
# Apply migrations to production
npm run db:migrate:prod
Verify Database Schema
Check that all tables were created:
# List tables in production database
wrangler d1 execute sonicjs-ai --env production \
--command="SELECT name FROM sqlite_master WHERE type='table';"
# Expected tables:
# - users
# - collections
# - content
# - content_versions
# - media
# - api_tokens
# - plugins
# - plugin_routes
# - plugin_hooks
Seed Initial Data
Create an admin user and initial collections:
Seed Data
wrangler d1 execute sonicjs-ai --env production --command="
INSERT INTO users (id, email, username, first_name, last_name, role, is_active, created_at, updated_at)
VALUES (
'admin-' || lower(hex(randomblob(16))),
'admin@yourdomain.com',
'admin',
'Admin',
'User',
'admin',
1,
strftime('%s', 'now') * 1000,
strftime('%s', 'now') * 1000
);
"
R2 Storage Setup
Create R2 Bucket
Create an R2 bucket for media storage:
Create R2 Bucket
# Create R2 bucket for production
wrangler r2 bucket create sonicjs-media-prod
# Verify creation
wrangler r2 bucket list
# Output:
# sonicjs-media-dev
# sonicjs-media-preview
# sonicjs-media-prod
Configure Custom Domain (Optional)
Set up a custom domain for public media access:
# In Cloudflare Dashboard:
# 1. Go to R2 > sonicjs-media-prod > Settings
# 2. Click "Connect Domain"
# 3. Enter: media.yourdomain.com
# 4. DNS records will be created automatically
# This allows public access to media files via:
# https://media.yourdomain.com/uploads/image.jpg
Bucket Organization
Recommended folder structure:
sonicjs-media-prod/
├── uploads/ # User uploaded media
├── avatars/ # User avatar images
├── thumbnails/ # Generated thumbnails
├── documents/ # PDF and documents
└── temp/ # Temporary files (auto-cleanup)
Supported File Types
- Images: JPEG, PNG, GIF, WebP, SVG
- Documents: PDF, TXT, DOC, DOCX
- Videos: MP4, WebM, OGG, AVI, MOV
- Audio: MP3, WAV, OGG, M4A
- Max File Size: 50MB
KV Cache Setup
Create KV Namespace
Create a KV namespace for caching:
Create KV Namespace
# Create KV namespace for cache
wrangler kv:namespace create "CACHE_KV" --env production
# Output:
# ✅ Created namespace with id "7171ca98640e43b6b33dbff516a5a6cf"
Verify KV Access
Test KV namespace access:
# List all KV namespaces
wrangler kv:namespace list
# Test write
wrangler kv:key put --binding CACHE_KV --env production "test" "Hello"
# Test read
wrangler kv:key get --binding CACHE_KV --env production "test"
# Delete test key
wrangler kv:key delete --binding CACHE_KV --env production "test"
Cache Usage
The cache plugin uses KV for:
- API response caching (5 min TTL)
- Collection metadata caching (2 hour TTL)
- Content caching (1 hour TTL)
- Admin dashboard stats (15 min TTL)
Cache keys follow the pattern:
cache:api:collections:all
cache:api:content-list:limit:50
cache:collection-content:blog-posts:limit:50
Environment Variables
Required Secrets
Set up required secrets for production:
Configure Secrets
# Generate and set JWT secret (required)
openssl rand -base64 32 | wrangler secret put JWT_SECRET --env production
Managing Secrets
Secret Management
# List all secrets (names only, not values)
wrangler secret list --env production
Public Variables
Configure public variables in wrangler.toml:
[env.production.vars]
ENVIRONMENT = "production"
# CDN_DOMAIN = "media.yourdomain.com"
# IMAGES_ACCOUNT_ID = "your-cloudflare-account-id"
# FEATURE_NEW_EDITOR = "true"
Deployment Workflow
Pre-deployment Checks
Run these checks before deploying:
Pre-deployment
# Run all tests
npm test
Deploy to Production
Deploy your application:
Production Deployment
# Option 1: Using predeploy script (runs tests + build)
npm run predeploy && npm run deploy
Post-deployment Verification
Verify the deployment:
Verify Deployment
# Check API health
curl https://sonicjs-ai-prod.workers.dev/api/health
# Expected response:
# {
# "status": "healthy",
# "timestamp": "2024-01-15T12:00:00.000Z",
# "schemas": ["users", "collections", "content", ...]
# }
Preview Deployment
Test changes in a preview environment first:
# Deploy to preview environment
wrangler deploy --env preview
# Output:
# ✅ Successfully deployed to preview
# URL: https://sonicjs-ai-preview.workers.dev
# Test the preview deployment
curl https://sonicjs-ai-preview.workers.dev/api/health
View Deployment History
# List recent deployments
wrangler deployments list --env production
# Output:
# Created ID Version
# 2024-01-15 abc123def456 v1.2.3
# 2024-01-14 def456abc789 v1.2.2
# 2024-01-13 ghi789jkl012 v1.2.1
Custom Domains
Add Custom Domain
Connect your custom domain to the Worker:
Via Cloudflare Dashboard
- Go to Workers & Pages > sonicjs-ai-prod
- Click Triggers tab
- Click Add Custom Domain
- Enter:
yourdomain.com - Click Add Custom Domain
Via wrangler.toml
[env.production]
name = "sonicjs-ai-prod"
routes = [
{ pattern = "yourdomain.com/*", zone_name = "yourdomain.com" },
{ pattern = "www.yourdomain.com/*", zone_name = "yourdomain.com" }
]
Then deploy:
wrangler deploy --env production
Configure DNS
Cloudflare automatically creates DNS records. Verify with:
# Check DNS propagation
dig yourdomain.com
# Or using nslookup
nslookup yourdomain.com
Manual DNS configuration (if needed):
Type: AAAA
Name: @
Content: 100::
Proxy: Enabled (orange cloud)
SSL Certificate
SSL is automatic with Cloudflare:
- Universal SSL - Issued automatically
- Edge Certificates - Free, auto-renewed
- Full (Strict) - Recommended encryption mode
Verify SSL:
# Check certificate
curl -vI https://yourdomain.com 2>&1 | grep -i "ssl\|tls"
# Or use SSL checker
# https://www.ssllabs.com/ssltest/analyze.html?d=yourdomain.com
Force HTTPS
Ensure all traffic uses HTTPS:
// In src/index.ts
app.use('*', async (c, next) => {
const url = new URL(c.req.url)
if (url.protocol === 'http:') {
url.protocol = 'https:'
return c.redirect(url.toString(), 301)
}
await next()
})
Production Checklist
Use this checklist before going live:
Infrastructure
- Production D1 database created and migrated
- Production R2 bucket created
- Production KV namespace created
- All bindings configured in wrangler.toml
- Secrets uploaded (JWT_SECRET, etc.)
- Custom domain added and DNS configured
- SSL certificate active and valid
Database
- All migrations applied successfully
- Initial data seeded (users, collections)
- Admin user created with secure password
- Database indexes verified
- Backup strategy in place
Application
- Health check endpoint responding
- API endpoints working correctly
- Admin panel accessible
- Authentication system working
- Media upload functionality tested
- Cache system operational
Security
- HTTPS enforced (no HTTP access)
- Strong JWT secret configured
- CORS properly configured
- Security headers configured
- Admin password is strong and unique
Performance
- Cache headers configured
- Static assets compressed
- Database queries optimized
- KV cache working correctly
- R2 CDN domain configured
Monitoring
- Error logging configured
- Performance monitoring enabled
- Uptime monitoring setup
- Alert notifications configured
- Log retention policy set
Monitoring
Real-time Logs
View production logs in real-time:
Log Monitoring
# Tail production logs
wrangler tail --env production
Cloudflare Analytics
Access analytics in the dashboard:
Workers & Pages > sonicjs-ai-prod > Analytics
Key metrics:
- Requests - Total requests and errors
- Success Rate - % of successful requests
- Duration - P50, P95, P99 response times
- CPU Time - Average CPU usage
- Errors - Error count and types
Health Check Monitoring
Set up external monitoring:
# Health check endpoint
GET https://yourdomain.com/api/health
# Expected response:
{
"status": "healthy",
"timestamp": "2024-01-15T12:00:00.000Z",
"schemas": ["users", "collections", "content", "media", "plugins"]
}
Recommended monitoring services:
- UptimeRobot - uptimerobot.com
- Pingdom - pingdom.com
- Better Uptime - betteruptime.com
Performance Monitoring
Every API response includes performance headers:
X-Cache-Status: HIT
X-Cache-Source: memory
X-Cache-TTL: 278
X-Response-Time: 3ms
Rollback Procedures
View Deployment History
# List recent deployments
wrangler deployments list --env production
# Output:
# Created ID Version
# 2024-01-15 abc123 v1.2.3 (current)
# 2024-01-14 def456 v1.2.2
# 2024-01-13 ghi789 v1.2.1
Rollback to Previous Version
Rollback
# Rollback to previous deployment
wrangler rollback --env production
# This will rollback to: v1.2.2
Rollback with Database
If the version included database migrations:
# 1. Export current database
wrangler d1 export sonicjs-ai --env production \
--output backup-before-rollback.sql
# 2. Rollback Worker deployment
wrangler rollback --env production
# 3. Check which migrations to revert
wrangler d1 migrations list DB --env production
# Note: D1 doesn't have automatic down migrations
# Manual SQL required for schema changes
Emergency Rollback Script
#!/bin/bash
# emergency-rollback.sh
echo "Starting emergency rollback..."
# 1. Backup current state
echo "Creating backup..."
wrangler d1 export sonicjs-ai --env production \
--output "emergency-backup-$(date +%Y%m%d-%H%M%S).sql"
# 2. Rollback deployment
echo "Rolling back deployment..."
wrangler rollback --env production
# 3. Verify health
echo "Verifying health..."
curl -f https://yourdomain.com/api/health || echo "❌ Health check failed"
echo "Rollback complete"
Troubleshooting
Database Connection Errors
Database Issues
# Error: D1_ERROR: no such table: users
Secrets Not Found
Secret Issues
# Error: Uncaught ReferenceError: JWT_SECRET is not defined
R2 Bucket Access Denied
R2 Issues
# Error: R2 bucket 'sonicjs-media-prod' not found
Performance Issues
Slow Database Queries
-- Add missing indexes
CREATE INDEX idx_content_status ON content(status);
CREATE INDEX idx_content_collection ON content(collection_id);
-- Analyze query performance
EXPLAIN QUERY PLAN SELECT * FROM content WHERE status = 'published';
Cache Not Working
# Verify cache headers
curl -I https://yourdomain.com/api/collections | grep -i cache
# Expected headers:
# X-Cache-Status: HIT
# X-Cache-Source: memory
# X-Cache-TTL: 278
Domain and SSL Issues
SSL Certificate Errors
# Check SSL status
curl -vI https://yourdomain.com 2>&1 | grep -i ssl
# Solutions:
# 1. Wait for certificate issuance (up to 24 hours)
# 2. Verify domain is proxied (orange cloud)
# 3. Check SSL/TLS mode is "Full (strict)"
Domain Not Routing
# Verify DNS
dig yourdomain.com
# Check Worker routes
wrangler routes list
# Verify route in wrangler.toml
Getting Help
- Cloudflare Community - community.cloudflare.com
- Discord - discord.gg/cloudflaredev
- Cloudflare Docs - developers.cloudflare.com/workers
- SonicJS Issues - github.com/lane711/sonicjs/issues
Next Steps
- Testing Guide - Test your deployment
- Database Documentation - Advanced database features
- API Reference - API endpoints reference
- Caching - Optimize cache configuration
For ongoing support, visit our Community page.