Cloudflare (Path B)
This guide covers deploying the LaunchSwift backend (Hono on Cloudflare Workers) to production. You have two options: Wrangler CLI or Alchemy IaC.
Prerequisites
Section titled “Prerequisites”- Cloudflare account
- Node.js 20+
- Wrangler CLI (
npm install -g wrangler) - Authenticated with Cloudflare:
wrangler login
1. Create D1 database
Section titled “1. Create D1 database”wrangler d1 create launchswift-dbCopy the database_id from the output and update backend/wrangler.toml:
[[d1_databases]]binding = "DB"database_name = "launchswift-db"database_id = "your-database-id-here"2. Create KV namespace
Section titled “2. Create KV namespace”wrangler kv namespace create RATE_LIMIT_KVCopy the id and update backend/wrangler.toml:
[[kv_namespaces]]binding = "RATE_LIMIT_KV"id = "your-kv-namespace-id-here"3. Run migrations
Section titled “3. Run migrations”Apply the database schema:
cd backendwrangler d1 migrations apply launchswift-db --remoteThis creates all schema tables: users, sessions, accounts, verifications, conversations, messages, user_settings, api_usage, and feedback.
4. Set secrets
Section titled “4. Set secrets”cd backendwrangler secret put BETTER_AUTH_SECRETwrangler secret put OPENAI_API_KEY # Optional — only if using OpenAIwrangler secret put ANTHROPIC_API_KEY # Optional — only if using Anthropicwrangler secret put GEMINI_API_KEY # Optional — only if using Geminiwrangler secret put APPLE_CLIENT_ID # Optional — for Apple OAuthwrangler secret put APPLE_CLIENT_SECRET # Optional — for Apple OAuthOnly BETTER_AUTH_SECRET is required. AI provider keys are only needed for the providers you want to support.
5. Update production config
Section titled “5. Update production config”In backend/wrangler.toml, update the production environment variables:
[vars]ENVIRONMENT = "production"CORS_ORIGIN = "https://your-app-domain.com"BETTER_AUTH_URL = "https://launchswift-backend.your-account.workers.dev"6. Deploy
Section titled “6. Deploy”Option A: Wrangler (simple)
Section titled “Option A: Wrangler (simple)”cd backendnpm run deployThis runs the deploy script from backend/package.json (wrangler deploy).
Option B: Alchemy (IaC)
Section titled “Option B: Alchemy (IaC)”Alchemy provides type-safe infrastructure-as-code deployment:
cd backendnpm run alchemy:deployThe Alchemy config in backend/alchemy.config.ts defines:
- D1 database resource
- KV namespace resource
- Worker resource and bindings (including env vars + secrets)
- Observability
7. Point the iOS app at production
Section titled “7. Point the iOS app at production”In ios/SwiftLaunch/Core/Config/AppConfig.swift, update the production URL used by production(for:):
apiBaseURL: URL(string: "https://launchswift-backend.your-account.workers.dev")!8. Verify deployment
Section titled “8. Verify deployment”curl https://launchswift-backend.your-account.workers.dev/healthzExpected response:
{ "status": "ok", "environment": "production", "timestamp": "2026-03-01T12:00:00.000Z"}Custom domain (optional)
Section titled “Custom domain (optional)”To use a custom domain instead of the .workers.dev URL:
- Add a custom domain in the Cloudflare dashboard (Workers & Pages > your worker > Settings > Domains)
- Update
CORS_ORIGINandBETTER_AUTH_URLinwrangler.toml - Update
apiBaseURLinsideAppConfig.production(for:)in the iOS app - Redeploy:
npm run deploy
Monitoring
Section titled “Monitoring”Cloudflare provides built-in observability:
- Workers Analytics — request count, CPU time, errors
- D1 Analytics — query count, rows read/written
- Real-time Logs —
wrangler tailfor live log streaming
wrangler tail # Stream live logs from productionTroubleshooting
Section titled “Troubleshooting””Missing required configuration” (503)
Section titled “”Missing required configuration” (503)”An AI provider API key is not set. Set it via wrangler secret put.
”Rate limit exceeded” (429)
Section titled “”Rate limit exceeded” (429)”The user has exceeded the configured limit. Adjust limits in wrangler.toml:
[vars]RATE_LIMIT_REQUESTS_PER_MINUTE = "120"RATE_LIMIT_REQUESTS_PER_DAY = "5000"D1 “table not found”
Section titled “D1 “table not found””Migrations haven’t been applied. Run:
wrangler d1 migrations apply launchswift-db --remoteCORS errors
Section titled “CORS errors”Make sure CORS_ORIGIN in wrangler.toml includes your app’s domain(s). The template defaults to localhost origins for development.