Configuration
Configure your Go Bananas! deployment.
Environment Variables
Worker Configuration (wrangler.jsonc vars)
jsonc
{
"vars": {
// Environment identifier
"ENVIRONMENT": "production",
// Logging level: debug, info, warn, error
"LOG_LEVEL": "info",
// Public URL for R2 bucket
"R2_PUBLIC_URL": "https://pub-xxx.r2.dev",
// Image optimization strategy: passthrough, cloudflare, wasm
"IMAGE_OPTIMIZATION_STRATEGY": "passthrough",
// Optional: Cloudflare Image Resizing worker URL
"IMAGE_RESIZE_WORKER_URL": "https://resize.your-domain.com",
// Optional: Auth token for resize worker
"IMAGE_RESIZE_AUTH_TOKEN": ""
}
}Secrets (wrangler secret put)
| Secret | Required | Description |
|---|---|---|
ENCRYPTION_KEY | Yes | 256-bit AES key (64-char hex) |
ADMIN_TOKEN | Yes | Admin API authentication |
SESSION_SECRET | No | Session signing key |
Generate Secrets
bash
# Generate 256-bit encryption key
openssl rand -hex 32
# Set via wrangler
wrangler secret put ENCRYPTION_KEY
wrangler secret put ADMIN_TOKENR2 Configuration
Enable Public Access
- Go to Cloudflare Dashboard → R2
- Select
go-bananas-imagesbucket - Click "Settings" → "Public access"
- Enable public access
- Copy the public URL (e.g.,
https://pub-xxx.r2.dev) - Update
R2_PUBLIC_URLin wrangler.jsonc
Custom Domain (Optional)
For branded URLs:
- Add custom domain in R2 bucket settings
- Configure DNS CNAME record
- Update
R2_PUBLIC_URLto your domain
jsonc
{
"vars": {
"R2_PUBLIC_URL": "https://images.yourdomain.com"
}
}CORS Configuration
Create cors.json:
json
[
{
"AllowedOrigins": ["*"],
"AllowedMethods": ["GET", "HEAD"],
"AllowedHeaders": ["*"],
"MaxAgeSeconds": 86400
}
]Apply CORS:
bash
wrangler r2 bucket cors put go-bananas-images --file cors.jsonD1 Database
Database Configuration
jsonc
{
"d1_databases": [
{
"binding": "DB",
"database_name": "go-bananas-db",
"database_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
]
}Multiple Environments
jsonc
{
"env": {
"development": {
"d1_databases": [
{
"binding": "DB",
"database_name": "go-bananas-db-dev",
"database_id": "dev-database-id"
}
]
},
"production": {
"d1_databases": [
{
"binding": "DB",
"database_name": "go-bananas-db",
"database_id": "prod-database-id"
}
]
}
}
}KV Namespaces
Configuration
jsonc
{
"kv_namespaces": [
{
"binding": "API_KEYS",
"id": "api-keys-namespace-id"
},
{
"binding": "TENANT_CONFIG",
"id": "tenant-config-namespace-id"
}
]
}Cache TTL Settings
Cache durations are configurable in code:
typescript
// API key cache: 5 minutes
await env.API_KEYS.put(apiKey, tenantId, { expirationTtl: 300 });
// Tenant config cache: 5 minutes
await env.TENANT_CONFIG.put(key, config, { expirationTtl: 300 });Durable Objects
Configuration
jsonc
{
"durable_objects": {
"bindings": [
{
"name": "MCP_OBJECT",
"class_name": "GoBananasMcpAgent"
}
]
},
"migrations": [
{
"tag": "v3",
"new_sqlite_classes": ["GoBananasMcpAgent"]
}
]
}Rate Limiting
Default Limits
Per-tenant rate limits stored in database:
| Setting | Default | Description |
|---|---|---|
rate_limit_per_minute | 60 | API requests per minute |
monthly_quota_mb | 1024 | Monthly storage quota |
Customize per Tenant
bash
curl -X PATCH "https://gobananasai.com/admin/tenants/acme-corp" \
-H "X-Admin-Token: admin_token" \
-H "Content-Type: application/json" \
-d '{
"rateLimitPerMinute": 120,
"monthlyQuotaMb": 10240
}'Image Optimization
Strategy: Passthrough (Default)
No image processing, stores as-is:
jsonc
{
"vars": {
"IMAGE_OPTIMIZATION_STRATEGY": "passthrough"
}
}Strategy: Cloudflare
Uses Cloudflare Image Resizing:
jsonc
{
"vars": {
"IMAGE_OPTIMIZATION_STRATEGY": "cloudflare",
"IMAGE_RESIZE_WORKER_URL": "https://resize.your-domain.com",
"IMAGE_RESIZE_AUTH_TOKEN": "secret-token"
}
}Strategy: WASM (Future)
WebAssembly-based processing:
jsonc
{
"vars": {
"IMAGE_OPTIMIZATION_STRATEGY": "wasm"
}
}Logging
Log Levels
jsonc
{
"vars": {
"LOG_LEVEL": "info" // debug, info, warn, error
}
}View Logs
bash
# Real-time logs
npm run tail
# Or directly
wrangler tailMulti-Environment Setup
Complete Example
jsonc
{
"name": "go-bananas",
"main": "src/index.ts",
"compatibility_date": "2024-01-01",
// Shared configuration
"durable_objects": {
"bindings": [
{
"name": "MCP_OBJECT",
"class_name": "GoBananasMcpAgent"
}
]
},
// Development environment
"env": {
"development": {
"vars": {
"ENVIRONMENT": "development",
"LOG_LEVEL": "debug",
"R2_PUBLIC_URL": "https://pub-xxx.r2.dev"
},
"d1_databases": [
{
"binding": "DB",
"database_name": "go-bananas-db-dev",
"database_id": "dev-db-id"
}
],
"r2_buckets": [
{
"binding": "R2_IMAGES",
"bucket_name": "go-bananas-images-dev"
}
],
"kv_namespaces": [
{
"binding": "API_KEYS",
"id": "dev-api-keys-id"
},
{
"binding": "TENANT_CONFIG",
"id": "dev-tenant-config-id"
}
]
},
// Production environment
"production": {
"vars": {
"ENVIRONMENT": "production",
"LOG_LEVEL": "info",
"R2_PUBLIC_URL": "https://images.yourdomain.com"
},
"d1_databases": [
{
"binding": "DB",
"database_name": "go-bananas-db",
"database_id": "prod-db-id"
}
],
"r2_buckets": [
{
"binding": "R2_IMAGES",
"bucket_name": "go-bananas-images"
}
],
"kv_namespaces": [
{
"binding": "API_KEYS",
"id": "prod-api-keys-id"
},
{
"binding": "TENANT_CONFIG",
"id": "prod-tenant-config-id"
}
]
}
}
}Deploy to Specific Environment
bash
# Development
wrangler deploy --env development
# Production
wrangler deploy --env productionSecurity Configuration
CORS Headers
Configured in src/api/http.ts:
typescript
const CORS_HEADERS = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, X-API-Key, Authorization, X-Session-Id',
'Access-Control-Max-Age': '86400',
};Restrict Origins
For production, restrict to specific origins:
typescript
const ALLOWED_ORIGINS = [
'https://yourdomain.com',
'https://app.yourdomain.com',
];