Deployment
How Docup is deployed: the Worker with the cf CLI, bindings and secrets in code, and tasks on Trigger.dev.
Docup deploys as a Cloudflare Worker plus Trigger.dev tasks. The Worker's settings live in code, in cloudflare.config.ts.
The Worker#
cloudflare.config.ts defines the Worker with defineConfig and defineWorker:
| Setting | Value |
|---|---|
| Name | docup |
| Entry point | ./worker.ts |
| Compatibility | Date 2026-10-21, flag nodejs_compat |
| Custom domain | docup.dev |
| Route | */* in the docup.dev zone, for docs sites and custom hostnames |
workers.dev |
Off. Preview URLs are on. |
| Placement | Region aws:ap-south-1, near the database |
| Observability | Logs, invocation logs, and traces persisted with head sampling rate 1, issues on |
| Assets | htmlHandling and notFoundHandling off, with the Worker running first for everything except /_next/static/*, /*/_next/static/*, /favicon.ico, /logo.svg, and /marketing/* |
A docs site needs the route in addition to the custom domain because a custom domain cannot be a wildcard. The */* route pattern catches both <address>.docup.dev subdomains and custom hostnames used for docs sites.
Bindings#
| Binding | Type | Purpose |
|---|---|---|
ASSETS |
Assets | Static files |
VERSION |
Version metadata | The id of the deploy, used in cache keys |
IMAGES |
Images | Image optimization |
ANALYTICS_ENGINE |
Analytics Engine dataset docup-docs-analytics |
One data point per docs view |
SITE_FILES |
R2 bucket docup-assets |
Uploaded logos, favicons and social images |
HYPERDRIVE |
Hyperdrive | Pooled Postgres connections. In development it points at the local Docker database. |
| Secrets | Secret | Everything in Environment variables that the Worker reads |
Deploying#
The Worker deploys from CI with cf deploy, which is strict: it stops if the Worker's settings in the Cloudflare dashboard differ from cloudflare.config.ts. For a manual deploy, pnpm run deploy runs vinext's Cloudflare deploy.
Never change Worker secrets, variables, bindings, routes or domains in the Cloudflare dashboard. A dashboard edit marks the Worker as edited, and the next CI deploy aborts with "Aborting the upload operation because of conflicts". Change settings in cloudflare.config.ts or with the cf CLI.
If that happens, run pnpm exec cf deploy once from a terminal and answer yes to "Would you like to continue?". That puts the Worker back to the repository's settings. The config lists the domain before the route, while Cloudflare returns the route first, so the two never match once the check runs.
Secrets#
Set each secret with the cf CLI. They are declared in the config as bindings.secret() and never stored in the repository. Tasks on Trigger.dev read their variables from the Trigger.dev dashboard instead.
Trigger.dev#
pnpm trigger:deployThis publishes the tasks in trigger/ to your Trigger.dev project. trigger.config.ts sets the task folder, the Node runtime, a hard stop of 3,600 seconds per task and default retries of three attempts with exponential backoff. The AI tasks override the default with a single attempt, because a retry would pay for every model call again.
Database migrations#
Run pnpm db:migrate against the target database before deploying code that needs a new column. See Database.
DNS#
The wildcard route works because *.docup.dev resolves to Cloudflare. Docs sites on a new address need no DNS change.