Skip to main content

Cloudflare Workers Deployment

Deploy Inkweld to Cloudflare's global edge network for low-latency access worldwide. This guide walks you through the interactive setup wizard - the easiest way to get started.

Overview

Cloudflare deployment uses:

  • Cloudflare Workers - Serverless backend API at the edge
  • Cloudflare Pages - Global CDN for the Angular frontend
  • D1 Database - SQLite-based database for user data and projects
  • R2 Storage - Object storage for media files (optional)
  • Durable Objects - Real-time collaborative editing with Yjs

Prerequisites

Before you begin:

  1. Cloudflare Account - Sign up free
  2. Git - For cloning the repository
  3. Bun 1.3+ - Backend runtime and package manager
Free Tier Available

Cloudflare offers generous free tiers for all required services. You can run Inkweld without any charges for development and small-scale use.

Quick Start with Setup Wizard

The setup wizard automates the entire deployment process:

# Clone the repository
git clone https://github.com/bobbyquantum/inkweld.git
cd inkweld

# Install dependencies
bun install

# Run the Cloudflare setup wizard
npm run cloudflare:setup

What the Wizard Does

The wizard guides you through each step:

============================================================
Inkweld Cloudflare Setup
============================================================

✅ Wrangler CLI is installed
✅ Logged in to Cloudflare

============================================================
Environment Selection
============================================================

Available environments:

preview - Pre-production environment for testing
production - Live production environment

Set up PREVIEW environment? (y/n): y
Set up PRODUCTION environment? (y/n): y

Step 1: Worker Configuration

The wizard detects your Cloudflare account and suggests unique worker names:

============================================================
Worker Configuration
============================================================

ℹ️ Worker names must be globally unique across all Cloudflare accounts.
ℹ️ Detected account: your-account-name

Worker name for PREVIEW (default: your-account-inkweld-preview):
✅ Preview worker URL: https://your-account-inkweld-preview.workers.dev
Continue with this URL? (y/n): y

Worker name for PRODUCTION (default: your-account-inkweld):
✅ Production worker URL: https://your-account-inkweld.workers.dev
Continue with this URL? (y/n): y
Worker Name Uniqueness

Worker names must be globally unique across all Cloudflare accounts. The wizard suggests names based on your account to avoid conflicts.

Step 2: Import Existing Configuration

If you're setting up on a new machine with existing deployments, the wizard can import your configuration:

Try to import existing environment variables from Cloudflare? (y/n): y
✅ Found existing preview configuration
✅ Found existing production configuration

Step 3: Create Resources

The wizard creates all required Cloudflare resources:

============================================================
Creating D1 Databases
============================================================

ℹ️ Creating D1 database: inkweld_preview...
✅ Created database "inkweld_preview" with ID: abc123...

ℹ️ Creating D1 database: inkweld_prod...
✅ Created database "inkweld_prod" with ID: def456...

============================================================
Creating R2 Storage Buckets
============================================================

✅ Created R2 bucket: inkweld-storage-preview
✅ Created R2 bucket: inkweld-storage

============================================================
Creating Cloudflare Pages Projects
============================================================

✅ Created Pages project: inkweld-frontend-preview
✅ Created Pages project: inkweld-frontend

Step 4: Generate Frontend Configuration

The wizard automatically generates environment files for the frontend:

============================================================
Generating Frontend Environment Files
============================================================

ℹ️ Frontend environment files configure the API URLs for each environment.
ℹ️ Workers will be available at:
ℹ️ Preview: https://your-account-inkweld-preview.workers.dev
ℹ️ Production: https://your-account-inkweld.workers.dev

✅ Generated environment.preview.ts
✅ Generated environment.cloudflare.ts

Step 5: Run Migrations

Apply the database schema:

============================================================
Running Database Migrations
============================================================

Run database migrations now? (y/n): y
ℹ️ Running migrations on inkweld_preview...
✅ Preview database migrated
ℹ️ Running migrations on inkweld_prod...
✅ Production database migrated

Step 6: Set Secrets

Configure sensitive values securely:

============================================================
Setting Secrets
============================================================

ℹ️ SESSION_SECRET is required for each environment.
ℹ️ This is a cryptographic key used to sign session cookies.
⚠️ CRITICAL: If this key is used for database encryption, changing it will
make existing data unreadable!

Generate and set SESSION_SECRET automatically? (y/n): y
✅ SESSION_SECRET set for preview
✅ SESSION_SECRET set for production

Deploy Your Application

After setup, deploy with:

# Deploy to preview (for testing)
npm run cloudflare:deploy:preview

# Deploy to production
npm run cloudflare:deploy:prod

The deploy commands:

  1. Build the Angular frontend with the correct environment
  2. Build the Cloudflare Worker backend
  3. Run any pending database migrations
  4. Deploy both frontend and backend

Manual Setup

If you prefer manual configuration, see the detailed steps below.

1. Login to Cloudflare

cd backend
bun run wrangler login

2. Create D1 Databases

bun run wrangler d1 create inkweld_preview
bun run wrangler d1 create inkweld_prod

Note the database_id values from the output.

3. Configure wrangler.toml

cp wrangler.toml.example wrangler.toml

Edit wrangler.toml and update the database IDs:

[[env.preview.d1_databases]]
binding = "DB"
database_name = "inkweld_preview"
database_id = "your-preview-database-id"
migrations_dir = "drizzle"

[[env.production.d1_databases]]
binding = "DB"
database_name = "inkweld_prod"
database_id = "your-production-database-id"
migrations_dir = "drizzle"

4. Run Migrations

bun run db:migrate:preview
bun run db:migrate:prod

5. Set Secrets

bun run wrangler secret put SESSION_SECRET --env preview
bun run wrangler secret put SESSION_SECRET --env production

6. Deploy

npm run cloudflare:deploy:preview
npm run cloudflare:deploy:prod

Custom Domain

To use your own domain instead of *.workers.dev and *.pages.dev:

Prerequisites

  1. Add your domain to Cloudflare - Transfer DNS or use Cloudflare as your DNS provider
  2. Verify domain ownership - Follow Cloudflare's verification steps

Using the Setup Wizard

The setup wizard prompts for custom domains for both preview and production environments:

Configure custom domains for preview? (y/n): y
Preview backend API domain (e.g., api.preview.yoursite.com): api.preview.inkweld.app
Preview frontend domain (e.g., preview.yoursite.com): preview.inkweld.app

Configure custom domains for production? (y/n): y
Production backend API domain (e.g., api.yoursite.com): api.inkweld.app
Production frontend domain (e.g., yoursite.com): inkweld.app

The wizard will:

  • Configure backend custom domains via routes in wrangler.toml (Workers support this)
  • Add frontend custom domains to ALLOWED_ORIGINS for CORS
  • Remind you to configure frontend custom domains in the Cloudflare Dashboard

Manual Configuration

Backend Custom Domain

Edit backend/wrangler.toml and uncomment/update the routes configuration:

# Preview
[env.preview]
name = "inkweld-backend-preview"
routes = [{ pattern = "api.preview.yoursite.com", custom_domain = true }]

# Production
[env.production]
name = "inkweld-backend-prod"
routes = [{ pattern = "api.yoursite.com", custom_domain = true }]

Or via Cloudflare Dashboard:

  1. Go to Workers & Pages → Your worker → SettingsTriggers
  2. Click Add Custom Domain
  3. Enter your domain (e.g., api.yoursite.com)

Frontend Custom Domain

Important: Unlike Workers, Cloudflare Pages does not support custom domain configuration via wrangler.toml. Custom domains for Pages must be configured in the Cloudflare Dashboard.

Via Cloudflare Dashboard (required for Pages):

  1. Go to Workers & Pages → Your Pages project → Custom domains
  2. Click Set up a custom domain
  3. Enter your domain (e.g., preview.yoursite.com or yoursite.com)
  4. Follow the DNS verification steps

Update ALLOWED_ORIGINS

After setting up custom domains, update ALLOWED_ORIGINS in backend/wrangler.toml:

[env.preview.vars]
ALLOWED_ORIGINS = "https://preview.yoursite.com"

[env.production.vars]
ALLOWED_ORIGINS = "https://yoursite.com,https://www.yoursite.com"

Redeploy

After making changes, redeploy both frontend and backend:

# Preview
npm run cloudflare:deploy:preview

# Production
npm run cloudflare:deploy:prod

Free Tier Limits

Cloudflare's free tier is generous for development and small teams:

ServiceFree Tier LimitNotes
Workers100K requests/day10ms CPU per request
D1 Database5M reads/day, 100K writes/day5GB storage
Durable Objects100K requests/day13K GB-seconds/day
R2 Storage10GB storageRequires payment method
PagesUnlimited sites500 builds/month
Understanding GB-seconds

Durable Objects are billed by memory × time. 13,000 GB-seconds translates to roughly 21 hours of continuous real-time collaboration per day.

Workers Paid Plan

For production use, consider the Workers Paid plan at $5/month:

  • 10 million requests/month (included)
  • 30 seconds CPU time per request
  • Higher D1 limits (25M reads, 50M writes/month)
  • 400K GB-seconds Durable Objects/month
  • Priority support

Monitoring

View Logs

# Stream real-time logs
bun run wrangler tail --env preview
bun run wrangler tail --env production

Analytics

In the Cloudflare dashboard:

  1. Go to Workers & Pages
  2. Select your worker
  3. Click Analytics for requests, errors, and performance

Troubleshooting

"Worker name already exists"

Worker names are globally unique. Choose a different name with your account prefix.

Database connection errors

Verify your database_id values in wrangler.toml match the actual D1 database IDs.

CORS errors

Update ALLOWED_ORIGINS to include all domains that need to access the API:

ALLOWED_ORIGINS = "https://yoursite.com,https://app.yoursite.com,https://preview.yoursite.com"

Real-time collaboration not working

Check that Durable Objects bindings are correctly configured and the worker deployed successfully.

Migration errors

Ensure migrations_dir = "drizzle" is set in all D1 database sections of your wrangler.toml.


Next Steps