Production
Ship TaskLabs behind Dokploy + Cloudflare Tunnel with automated daily backups to S3-compatible storage.
The production stack
Production runs the same product shape as development: the Next.js frontend, the self-hosted Convex backend, Convex storage on Postgres, the dashboard, and a db-backup scheduler. The only intentional dev difference is hot reload — production has no watcher services, no source bind mounts, and no pnpm dev.
- The frontend starts with
next starton an explicit host and internal port. - A build-time
NEXT_TURBOPACK_ROOTlets Next resolve the monorepo root and sibling Convex imports. - The dashboard stays internal — reach it over an SSH tunnel, never a public domain.
- All five prod services are health-checked by Compose.
Origins & CORS
Public domains map to container ports: the frontend, the Convex API, and the Convex site proxy each get their own subdomain. FRONTEND_ORIGIN and CORS_ALLOWED_ORIGINS list these exact HTTPS origins, and CORS_ALLOWED_ORIGINS also accepts proxy-forwarded public hosts for Cloudflare/Dokploy.
Daily backups
The db-backup service runs a Postgres-only pg_dump --format custom at midnight EAT, uploads the dump to the configured RustFS bucket via the S3 API, and sends a Telegram confirmation with backup-specific bot credentials. Dev carries the same service behind a backup profile to keep stack parity without running scheduled dumps during hot reload.
- RustFS endpoint, region, and access keys come from
.env— never from source code. - The healthcheck confirms
crondand the RustFS bucket before reporting healthy.
Convex Auth env
Self-hosted Convex Auth requires deployment env synced before functions deploy: SITE_URL, JWT_PRIVATE_KEY, and JWKS. The production deploy profile syncs these before pushing functions. Verify the OIDC and JWKS well-known endpoints after a change.
Security checklist
- The prod admin key is generated on the live backend container, never hand-edited, and stored only in gitignored
.envfiles. POSTGRES_URLstays cluster-only; a /<database> path makes the backend exit.- No wildcard CORS and no local origin fallbacks.
- Telegram origins are explicit env only.
- Never commit
.env,.env.dev, or generated secrets.