Deployment¶
Backend¶
Environment Variables¶
# Production
DATABASE_URL=postgresql://user:pass@host:5432/saas_courier
SECRET_KEY=your-production-secret
ENVIRONMENT=production
# Optional
RESEND_API_KEY=your-resend-api-key
AERODATABOX_API_KEY=your-rapidapi-key
Running¶
# Build
uv run pip install -e .
# Run
uv run gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000
Frontend¶
Build¶
Environment¶
Documentation (Cloudflare Workers)¶
Architecture¶
The documentation site uses Cloudflare Workers with KV storage for serving static files.
┌─────────────┐ ┌──────────────────┐ ┌─────────────┐
│ GitHub │────▶│ GitHub Actions │────▶│ Cloudflare │
│ Push │ │ mkdocs build │ │ Workers │
└─────────────┘ │ wrangler deploy│ │ + KV Store│
└──────────────────┘ └─────────────┘
Requirements¶
| Requirement | Version | Notes |
|---|---|---|
| Node.js | >= 22.0.0 | Wrangler 4.x requires Node.js 22+ |
| Python | 3.12 | For mkdocs |
| Wrangler | 4.x | Installed via npm |
GitHub Actions Workflow¶
Location: .github/workflows/deploy-docs.yml
Trigger paths:
on:
push:
branches: [main]
paths:
- 'docs/**'
- 'mkdocs.yml'
- 'wrangler.toml'
- '.github/workflows/**'
- 'workers-site/**'
⚠️ Important: The workers-site/** and .github/workflows/** paths must be included in the trigger configuration. Without these, workflow may not trigger on workers-site changes or workflow modifications.
Wrangler Configuration¶
File: wrangler.toml
name = "saas-courier-docs"
compatibility_date = "2026-05-15"
main = "workers-site/index.js"
compatibility_flags = ["nodejs_compat"]
[[kv_namespaces]]
binding = "ASSETS"
id = "af529f0e7da645da9d39ed407c5a11f2"
[site]
bucket = "./site"
| Field | Description |
|---|---|
main |
Entry point for Cloudflare Workers |
[site] bucket |
Static files output directory (from mkdocs build) |
[kv_namespaces] |
KV namespace for asset caching |
Workers Site¶
The workers-site/index.js file handles KV-based asset serving:
import { getAssetFromKV } from '@cloudflare/kv-asset-handler';
addEventListener('fetch', event => {
event.respondWith(handleEvent(event));
});
async function handleEvent(event) {
try {
return await getAssetFromKV(event);
} catch (e) {
console.error('Error serving asset:', e);
return new Response('Error loading page', { status: 500 });
}
}
Deploy¶
Custom Domain¶
Troubleshooting¶
Wrangler requires Node.js v22.0.0¶
Error:
Solution: Update Node.js version in GitHub Actions workflow:
Build failed - Could not resolve "@cloudflare/kv-asset-handler"¶
Cause: Missing or incorrect workers-site configuration.
Solution: Ensure:
1. workers-site/index.js exists in repository
2. main = "workers-site/index.js" is in wrangler.toml
3. @cloudflare/kv-asset-handler is in package.json dependencies
Workflow not triggering¶
Cause: Missing paths in workflow trigger configuration.
Solution: Ensure trigger includes:
Workers Sites deprecated warning¶
Warning:
Because you've defined a [site] configuration, we're defaulting to "workers-site"
for the deprecated `site.entry-point` field.
This is expected. The workers-site approach is still functional.
Environment Reference¶
| Variable | Description |
|---|---|
DATABASE_URL |
PostgreSQL connection string |
SECRET_KEY |
JWT signing key (min 32 chars) |
ENVIRONMENT |
development or production |
CORS_ORIGINS |
Allowed origins (comma-separated) |