Deployment
Self-host opensesh on Cloudflare Workers with Postgres, R2, and Hyperdrive.
opensesh is MIT-licensed and self-hostable. The app is a single Cloudflare Worker (SSR + API) in front of a Postgres database, connected through Cloudflare Hyperdrive. File uploads go to R2 and transactional email goes out through a send-email binding.
Prerequisites
- A Cloudflare account with Workers enabled
- A Postgres database reachable from Cloudflare (any managed Postgres works)
- Node.js and pnpm
wranglerauthenticated against your account (wrangler login)
Deploy
Clone and install
git clone <your-fork-of-opensesh>
cd opensesh
pnpm installThe repo is a pnpm workspace; the product lives in apps/web.
Create the Hyperdrive config
Hyperdrive pools and accelerates Postgres connections from the edge:
wrangler hyperdrive create opensesh-db \
--connection-string="postgres://user:pass@host:5432/opensesh"Put the returned id into apps/web/wrangler.jsonc under the hyperdrive binding (the binding name is HYPERDRIVE). While you're in that file, also update:
name— your worker nameroutes— your custom domain (the hosted app usesapp.opensesh.io)r2_buckets— theFILESbinding needs an R2 bucket for speaker uploads (wrangler r2 bucket create opensesh-files)send_email— theEMAILbinding for outbound mailplacement.region— pin the Worker next to your database (for exampleaws:us-east-1)vars—DEMO_MODE(set0for a real deployment),MAIL_PROVIDER,MAIL_FROM
Placement matters
Without placement.region, the Worker runs wherever the visitor is and every query pays
cross-continent latency. Pinned next to the database, round-trips stay at 1–5 ms.
Run migrations and seed
Generate and apply the schema from packages/domain (Drizzle), then optionally seed the demo event:
pnpm db:generate
pnpm seed # optional: demo event + personasSet secrets
Two secrets, set on the worker:
wrangler secret put BETTER_AUTH_SECRET # session/token signing — use a long random string
wrangler secret put ANTHROPIC_API_KEY # optional — enables AI reviews and AI agenda draftsANTHROPIC_API_KEY is optional
Without it the app runs fine — the Run AI review button in Evaluation and the AI draft generator in Agenda simply stay disabled.
Deploy
pnpm --filter @opensesh/web deploy
# equivalent to: build + wrangler deploy from apps/webPoint your DNS at the custom domain route and you're live. Subsequent deploys are the same command; migrations are applied against Postgres directly, so run them before deploying schema-dependent changes.
Troubleshooting
Check that placement.region matches your database region and that Hyperdrive caching settings
suit your workload.
The worker has no ANTHROPIC_API_KEY secret; set it and redeploy.
With MAIL_PROVIDER=demo mail is captured in the in-app demo inbox (Email delivery page)
instead of being sent. Configure a real provider and MAIL_FROM for production.