Skip to content

Production Deployment

Temp edited this page Feb 11, 2026 · 6 revisions

Production Deployment

Complete guide to deploying D1 Database Manager to Cloudflare Workers for production use.

Prerequisites

Before deploying, ensure you have:

  • βœ… Cloudflare account (Sign up free)
  • βœ… Wrangler CLI installed (npm install -g wrangler)
  • βœ… Domain in Cloudflare (optional - can use workers.dev)
  • βœ… D1 Manager source code
  • βœ… Cloudflare Access configured (see Authentication Setup)

Deployment Overview

Local Development β†’ Build Frontend β†’ Configure Worker β†’ Set Secrets β†’ Deploy

Step-by-Step Deployment

Step 1: Install Wrangler CLI

# Install globally
npm install -g wrangler

# Or use with npx (no global install needed)
npx wrangler --version

Step 2: Authenticate with Cloudflare

wrangler login

This opens a browser for authentication. Grant access when prompted.

Verify authentication:

wrangler whoami

Step 3: Create Production Configuration

Edit wrangler.toml with your configuration:

name = "d1-manager"
main = "worker/index.ts"
compatibility_date = "2024-10-15"
workers_dev = false

# Asset configuration for serving frontend
[assets]
directory = "dist"
binding = "ASSETS"

# Optional: Custom domain routing
[[routes]]
pattern = "d1.yourdomain.com/*"
zone_name = "yourdomain.com"

# D1 database binding
[[d1_databases]]
binding = "DB"
database_name = "d1-manager-metadata"
database_id = ""  # Fill in after Step 4

# Enable observability
[observability]
enabled = true

Configuration Notes:

  • Replace d1.yourdomain.com with your domain
  • Replace yourdomain.com with your zone name
  • Leave database_id empty for now (filled in Step 4)

Step 4: Create Metadata Database

Create the D1 database for storing query history and saved queries:

# Create database
wrangler d1 create d1-manager-metadata

Output:

βœ… Successfully created DB 'd1-manager-metadata'!

[[d1_databases]]
binding = "DB"
database_name = "d1-manager-metadata"
database_id = "a1b2c3d4-e5f6-7890-abcd-ef1234567890"

Copy the database_id and add it to your wrangler.toml.

Initialize the schema:

wrangler d1 execute d1-manager-metadata --remote --file=worker/schema.sql

Note for existing users upgrading: If you're upgrading from an earlier version, run this command again to add new tables (like undo_history for the rollback feature). Existing tables won't be affected:

# Safe to run on existing metadata database
wrangler d1 execute d1-manager-metadata --remote --file=worker/schema.sql

Verify:

wrangler d1 execute d1-manager-metadata --remote --command="SELECT name FROM sqlite_master WHERE type='table';"

You should see tables including: query_history, saved_queries, and undo_history.

Step 5: Set Up R2 Backup Bucket (Optional)

To enable database backups to R2 storage:

# Create the R2 bucket
npx wrangler r2 bucket create d1-manager-backups

Add R2 and Durable Object configuration to your wrangler.toml:

# R2 Backup Bucket
[[r2_buckets]]
binding = "BACKUP_BUCKET"
bucket_name = "d1-manager-backups"

# Durable Objects for async backup processing
[[durable_objects.bindings]]
name = "BACKUP_DO"
class_name = "BackupDO"
script_name = "d1-manager"

[[migrations]]
tag = "v1"
new_classes = ["BackupDO"]

Note: The wrangler.toml includes this configuration. R2 backup enables cloud storage for database backups with one-click restore. See R2-Backup-Restore for complete documentation.

Step 6: Set Up Cloudflare Access

See Authentication Setup for complete instructions.

Quick checklist:

  • βœ… Identity provider configured (GitHub, Google, etc.)
  • βœ… Access application created
  • βœ… Policies configured
  • βœ… Application AUD tag obtained
  • βœ… Team domain obtained

Step 7: Configure Worker Secrets

Set all required secrets using Wrangler:

# Cloudflare Account ID
wrangler secret put ACCOUNT_ID
# Enter: your-account-id

# Cloudflare API Token (with D1 Edit permission)
wrangler secret put API_KEY
# Enter: your-api-token

# Cloudflare Access Team Domain
wrangler secret put TEAM_DOMAIN
# Enter: https://yourteam.cloudflareaccess.com

# Cloudflare Access Application AUD
wrangler secret put POLICY_AUD
# Enter: your-aud-tag

Find your Account ID:

Dashboard URL: https://dash.cloudflare.com/YOUR_ACCOUNT_ID

Create API Token:

  1. Go to API Tokens
  2. Click Create Token β†’ Create Custom Token
  3. Name: D1-Manager-Token
  4. Permissions: Account β†’ D1 β†’ Edit
  5. Click Create Token
  6. Copy the token (shown only once)

Verify secrets:

wrangler secret list

Step 8: Configure Frontend for Production

Edit .env to disable local API:

# .env (production)

# Comment out or remove this line
# VITE_WORKER_API=http://localhost:8787

# When undefined, app uses window.location.origin

Step 9: Build Frontend

# Install dependencies (if not already done)
npm install

# Build production bundle
npm run build

Output:

vite v7.1.12 building for production...
βœ“ 1234 modules transformed.
dist/index.html                   0.45 kB β”‚ gzip: 0.30 kB
dist/assets/index-CkbgeJUQ.css   45.23 kB β”‚ gzip: 8.12 kB
dist/assets/index-CNIKIAND.js   456.78 kB β”‚ gzip: 123.45 kB
βœ“ built in 5.67s

Verify build:

ls -lh dist/

Step 10: Deploy to Cloudflare Workers

# Deploy everything
wrangler deploy

Output:

Total Upload: 512.34 KiB / gzip: 145.67 KiB
Uploaded d1-manager (1.23 sec)
Published d1-manager (2.34 sec)
  https://d1-manager.your-account.workers.dev
  https://d1.yourdomain.com (custom domain)
Current Deployment ID: abc123def456

Step 11: Verify Deployment

  1. Visit your Worker URL:

    • https://d1-manager.your-account.workers.dev
    • Or https://d1.yourdomain.com (custom domain)
  2. You should see:

    • Cloudflare Access login page
    • Authenticate with your identity provider
    • D1 Manager interface loads
    • Real D1 databases appear (not mock data)
  3. Test functionality:

    • List databases
    • Create a test database
    • View tables
    • Execute queries

Custom Domain Setup

Option 1: Using Cloudflare DNS

If your domain is in Cloudflare:

  1. Add route to wrangler.toml:
[[routes]]
pattern = "d1.yourdomain.com/*"
zone_name = "yourdomain.com"
  1. Deploy:
wrangler deploy

Cloudflare automatically creates the DNS record.

Option 2: Manual DNS Setup

If using external DNS:

  1. Create CNAME record:
Type: CNAME
Name: d1
Value: your-worker-name.your-account.workers.dev
  1. Add route to wrangler.toml:
[[routes]]
pattern = "d1.yourdomain.com/*"
zone_name = "yourdomain.com"
  1. Deploy:
wrangler deploy

Multiple Domains

Support multiple domains in one deployment:

[[routes]]
pattern = "d1.yourdomain.com/*"
zone_name = "yourdomain.com"

[[routes]]
pattern = "database.example.com/*"
zone_name = "example.com"

Environment Management

Multiple Environments

Create separate configs for different environments:

wrangler.production.toml:

name = "d1-manager-prod"
# ... production config

wrangler.staging.toml:

name = "d1-manager-staging"
# ... staging config

Deploy to specific environment:

# Staging
wrangler deploy --config wrangler.staging.toml

# Production
wrangler deploy --config wrangler.production.toml

Environment-Specific Secrets

Set secrets per environment:

# Staging secrets
wrangler secret put ACCOUNT_ID --config wrangler.staging.toml

# Production secrets
wrangler secret put ACCOUNT_ID --config wrangler.production.toml

Deployment Best Practices

1. Test Before Deploying

# Dry run (test without deploying)
wrangler deploy --dry-run

# Or deploy to workers.dev first
wrangler deploy --no-bundle

2. Version Your Deployments

Use git tags:

git tag -a v1.0.0 -m "Production release 1.0.0"
git push origin v1.0.0

Update VERSION file:

echo "1.0.0" > VERSION
git commit -am "Bump version to 1.0.0"

3. Monitor Deployments

Enable observability:

[observability]
enabled = true

View logs:

wrangler tail

4. Rollback if Needed

Wrangler keeps deployment history:

# List deployments
wrangler deployments list

# Rollback to previous
wrangler rollback

5. Use CI/CD

Automate deployments with GitHub Actions:

# .github/workflows/deploy.yml
name: Deploy to Cloudflare Workers

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version: "22"
      - run: npm install
      - run: npm run build
      - uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}

Monitoring & Observability

Worker Analytics

View in Cloudflare Dashboard:

  1. Go to Workers & Pages
  2. Select your Worker
  3. Click Analytics

Metrics:

  • Request count
  • Error rate
  • CPU time
  • Duration (p50, p95, p99)

Real-Time Logs

Tail logs in real-time:

wrangler tail

Filter logs:

# Only errors
wrangler tail --status error

# Specific status codes
wrangler tail --status ok

# Search for text
wrangler tail --search "database"

Error Tracking

The Worker catches and logs errors:

// worker/index.ts
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    try {
      return await handleApiRequest(request, env);
    } catch (err) {
      console.error("[Worker] Unhandled error:", err);
      return new Response(
        JSON.stringify({
          error: "Internal Server Error",
        }),
        { status: 500 },
      );
    }
  },
};

View errors in logs:

wrangler tail | grep ERROR

Access Logs

Monitor authentication in Cloudflare Zero Trust:

  1. Go to Zero Trust β†’ Logs β†’ Access
  2. Filter by application name
  3. Review authentication events

Scaling Considerations

Cloudflare Workers Limits

Free Plan:

  • 100,000 requests/day
  • 10ms CPU time per request
  • No D1 limits

Paid Plan ($5/month):

  • Unlimited requests
  • 50ms CPU time per request
  • Pay-as-you-go for extra CPU

D1 Limits (as of 2024):

  • 10GB storage per database
  • 5GB reads/day (free)
  • 100,000 writes/day (free)

Performance Optimization

  1. Enable Caching:
[assets.cache]
max_age = 31536000  # 1 year for static assets
  1. Minimize Asset Size:
# Production build optimizations in vite.config.ts
build: {
  minify: 'esbuild',
  cssMinify: true,
  rollupOptions: {
    output: {
      manualChunks: {
        vendor: ['react', 'react-dom']
      }
    }
  }
}
  1. Use Connection Pooling:

D1 automatically handles connection pooling.

High Traffic

For high-traffic deployments:

  1. Monitor Quotas:
# Check D1 usage
wrangler d1 info d1-manager-metadata
  1. Upgrade Plan if Needed:

Visit Cloudflare Dashboard β†’ Account β†’ Plans & Billing

  1. Implement Rate Limiting:

Add rate limiting in Worker if needed.

Security Hardening

1. Content Security Policy

Add CSP headers in Worker:

// worker/utils/cors.ts
headers.set(
  "Content-Security-Policy",
  "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';",
);

2. API Token Permissions

Use minimal permissions:

  • βœ… Account β†’ D1 β†’ Edit
  • ❌ Not Global API Key

3. Rotate Secrets Regularly

# Generate new API token
# Update secret
wrangler secret put API_KEY

4. Enable HTTPS Only

Cloudflare Workers use HTTPS by default.

5. Restrict Access Policies

In Cloudflare Access, use specific rules:

Include: Email ends with @yourcompany.com
Exclude: Country is in [blocked countries]

Troubleshooting Deployment

"Failed to publish"

Cause: Build errors or missing configuration

Solution:

# Check build
npm run build

# Validate wrangler.toml
wrangler validate

"Authentication error"

Cause: Not logged in to Wrangler

Solution:

wrangler logout
wrangler login

"Database not found"

Cause: D1 database not created or wrong ID

Solution:

# List databases
wrangler d1 list

# Verify database_id in wrangler.toml

"Failed to list databases" in production

Cause: Missing or incorrect secrets

Solution:

# Verify secrets
wrangler secret list

# Re-set secrets
wrangler secret put ACCOUNT_ID
wrangler secret put API_KEY

"Mock data in production"

Cause: Frontend still configured for local dev

Solution:

# Edit .env - comment out VITE_WORKER_API
# Rebuild and redeploy
npm run build
wrangler deploy

"Access application not working"

See Authentication Setup troubleshooting section.

Updating Production

Update Process

# 1. Pull latest changes
git pull origin main

# 2. Install dependencies
npm install

# 3. Build frontend
npm run build

# 4. Deploy
wrangler deploy

Zero-Downtime Updates

Cloudflare Workers deployments are atomic:

  • New version uploaded
  • Traffic switches instantly
  • No downtime

Rollback

If something goes wrong:

# View deployment history
wrangler deployments list

# Rollback to previous version
wrangler rollback

Cost Estimation

Cloudflare Workers

Free Tier:

  • Workers: 100,000 requests/day
  • D1: 5GB reads, 100,000 writes/day
  • Cost: $0

Paid Plan ($5/month):

  • Workers: Unlimited requests, 10M CPU ms
  • D1: Included storage, pay for additional I/O
  • Cost: $5-10/month for typical usage

Custom Domain

Free if domain is in Cloudflare (DNS only)

Cloudflare Access

Free Tier:

  • Up to 50 users
  • Cost: $0

Teams Plan ($7/user/month):

  • Unlimited users
  • Advanced features

Next Steps


Need Help? See Troubleshooting or open an issue.

Clone this wiki locally