deploy + ops

3 tiers · Cloudflare Pages · Fly.io · Neon Postgres
live buildv1.1.0-autotest · fbc0555 · deployed 2026-07-03 22:51 UTC

Tier topology

tierweb URLCF Pages projectFly Hocuspocus appNeon branchbeta gate
prodpatchtogether.livepatchtogether-livepatchtogether-serverproductionoff
autotestautotest.patchtogether.livepatchtogether-live-autotestpatchtogether-server-autotestautotestbeta:robotsonly
devdev.patchtogether.livepatchtogether-live-devpatchtogether-server-devdevbeta:2600hz

What deploys when

  • PR open / push → preview at pr-N.patchtogether-live-autotest.pages.dev. Inherits the autotest Clerk env so auth round-trips work.
  • merge to main → autotest + dev fan-out, in parallel. Both stay in sync.
  • version bump on main → prod deploy. Detected by diffing package.json:.version against HEAD~1.
  • workflow_dispatch → manual override. Requires the latest CI run on the chosen branch to be green.

Why Cloudflare Pages can't drive Postgres directly

Three Postgres drivers were tried in sequence; only one works from Workers:

  • pg.Client over TCP — fails. Workers' node:net shim returns "proxy request failed"; pg's socket layer doesn't speak cloudflare:sockets.
  • @neondatabase/serverless WebSocket Pool — fails. CF's egress proxy 403s the outbound WebSocket handshake.
  • @neondatabase/serverless HTTP neon template tag — works. fetch() under the hood.

Consequence: anything in packages/web/src/lib/server/ that needs atomicity has to be a single SQL statement, typically a CTE. See rackspaces.ts for the pattern. The Hocuspocus server on Fly is regular Node — it uses pg.Pool over TCP without trouble.

Beta gate

Basic-auth wrapper enforced in hooks.server.ts. Off in prod, on in autotest + dev. /api/health bypasses the gate (live-smoke + uptime probes), and so does the /docs/* tree (so the in-app docs read the same pre- and post-launch). Browser auth + session flows still work behind it because Playwright passes credentials via use.httpCredentials.

Hocuspocus on Fly

Three Fly apps, one per tier. Each app runs the @patchtogether.live/server Node bundle — Hocuspocus + Clerk JWT verification + capacity enforcement (4 connections per doc). Yjs snapshots flush to the matching Neon branch. WebSocket URL is baked into the web bundle at build time via VITE_SERVER_WS_URL.

Local dev shortcut

flox activate -- task setup     # install + Playwright Chromium
flox activate -- task dev       # SvelteKit + DSP one-shot build
flox activate -- task server:dev # Hocuspocus on ws://localhost:1235

Hocuspocus binds 1235, not 1234 — BitwigStudio reserves 1234 for OSC on this machine. Postgres for local dev: see db/README.md.

Generated from packages/web/src/lib/{audio,video}/module-registry.ts · repo