PORT=3000 # Postgres, routed through pgCat/PgBouncer DATABASE_URL=postgres://continuum:continuum@localhost:6432/continuum DATABASE_POOL_MAX=10 # Valkey (state + streams), NOT Redis - Redis 7.4+ is RSALv2/SSPL and 8.0+ # adds AGPLv3, none of which we can ship commercially. Valkey is BSD-3-Clause # and wire-compatible. The URL scheme stays `redis://` because that names the # RESP wire protocol, which is what the client libraries parse - no client # understands a `valkey://` scheme. VALKEY_URL=redis://localhost:6379 # Cloudflare R2 (S3-compatible). The two credentials are required and the # process will not start without them: an empty key signs presigned URLs that # R2 answers with a 403, which surfaced as a gateway downloading an XML error # document in place of a print rather than as "R2 is not configured". # # Either R2_ENDPOINT or R2_ACCOUNT_ID is needed too - the endpoint is derived # from the account id the way Cloudflare's own URLs are formed. R2_BUCKET is # not a credential and defaults to "continuum". R2_ACCOUNT_ID= R2_BUCKET=continuum R2_ENDPOINT= R2_ACCESS_KEY_ID= R2_SECRET_ACCESS_KEY= # Cloudflare Realtime TURN, for relaying printer camera video. # # Optional, and unset is a supported state rather than a broken one: with no # TURN the console can still play a camera for a viewer on the gateway's own # network, over host candidates. Remote viewers need this. # # Why a relay at all: a browser cannot reach a gateway directly. go2rtc sends # no CORS headers and checks its API password before CORS, so a browser's # unauthenticated preflight gets a 401 - and a gateway is behind a workshop # NAT besides. Only the SDP exchange is relayed by this backend; the media # goes browser-to-gateway through TURN, DTLS-SRTP encrypted, so neither this # process nor Cloudflare can read it. # # The browser is pinned to relay-only when these are set, so video never goes # peer-to-peer and behaves the same on every customer network. Credentials # are minted per request with a 1 hour TTL (src/camera/ice.ts). # CLOUDFLARE_TURN_KEY_ID= # CLOUDFLARE_TURN_API_TOKEN= # Supabase Auth. Access tokens are verified against this project's published # JWKS (RS256), so no signing secret is needed - or wanted - here. SUPABASE_URL= # Signs the edge JWTs minted for continuum-proxy gateways via # POST /auth/edge-token and verified by /ws/edge/v1. Required - the process # refuses to start without it, because anything that knows this secret can # connect as any farm's gateway. Generate one with: openssl rand -hex 32 EDGE_JWT_SECRET=