.env.example and the README still told people to use pgCat on :6432, the exact setup that hangs on every parameterised query. With no prod and one backend instance there is nothing for a pooler to multiplex, and postgres-js already pools in-process, so DATABASE_URL now points at Postgres on :5432 in .env.example, dev-env.sh and drizzle.config.ts. prepare:false is kept in src/db/index.ts on purpose, so adding PgBouncer later (tested working) is a config change rather than a code change. The long measurement narrative in that file's comment is cut to the decision and the pointer to PLAN.md, where the numbers now live.
56 lines
2.5 KiB
Bash
56 lines
2.5 KiB
Bash
PORT=3000
|
|
|
|
# Postgres, directly - no pooler for the MVP (see src/db/index.ts)
|
|
DATABASE_URL=postgres://continuum:continuum@localhost:5432/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=
|