Render
Run the node deploy target on Render as a managed Web Service built from the owner app's Dockerfile, with attached Postgres and a Key Value cache.
Render is managed cloud for long-running web services. It runs the standard node target - the same Dockerfile you would run anywhere - and supports both fullstack and separate.
Deploy
Choose the Docker runtime so Render builds the owner app's Dockerfile - the frontend app's for fullstack, apps/backend/Dockerfile (EXPOSE 3010) for separate. A Node build also works; the Dockerfile is the portable default.
For a frontend image, set NEXT_PUBLIC_API_URL=https://yourdomain.com/api as an environment variable before the first build - Render exposes env vars to Docker builds, and Next.js bakes it into the browser bundle at build time (see Self-hosting with Docker).
DATABASE_URL. For cache, the provider chosen at init decides the vars - see the table below and Caching.CMD pnpm start. The schema step the CLI prepended to the owner's start script applies migrations before the server boots.*.onrender.com URL, or attach a custom domain. Set that origin as API_URL / BASE_URL and add it to TRUSTED_ORIGINS.Required environment variables
Set these before the first deploy - validated at boot by @repo/runtime. Full list in Environment variables.
| Variable | Purpose |
|---|---|
DATABASE_URL | Postgres connection, required by the boot-time schema step |
BETTER_AUTH_SECRET | Auth signing secret, min 32 chars |
API_URL | The backend's public URL - your Render domain |
REDIS_URL | Cache connection, only on the self-hosted Redis variant |
UPSTASH_REDIS_REST_URL, UPSTASH_REDIS_REST_TOKEN | Cache connection, only on the Upstash variant |
INNGEST_APP_ID, INNGEST_EVENT_KEY, INNGEST_BASE_URL | Background jobs |
TRUSTED_ORIGINS | Comma-separated production domains for CORS and Better Auth |
TRUSTED_PROXY | Not needed - Render's load balancer is detected from its own RENDER variable. Verify per Client IP |
Database and cache options
The cache provider is fixed at init - set the vars for that variant only, never both.
| Service | Render-hosted | External managed |
|---|---|---|
| Postgres | Render PostgreSQL → DATABASE_URL | Neon or Supabase → DATABASE_URL (Database) |
| Cache (Redis variant) | Render Key Value → REDIS_URL | Self-hosted Redis → REDIS_URL |
| Cache (Upstash variant) | - | Upstash → UPSTASH_REDIS_REST_URL + UPSTASH_REDIS_REST_TOKEN |
pnpm infra has no place here - it is local development only. On Render the database and cache are managed services you attach.
Never deploy a --demo build - its schema step resets the database and force-pushes the schema on every boot.
Self-hosting with Docker
How the multi-stage image is built and the schema step runs on boot.
Separate backend
Run the standalone Hono server on API_PORT for independent scaling.
Reverse proxy
Front multiple long-running apps by host and path.
Going to production
The full pre-launch checklist before you ship.
Fly.io
Run the node deploy target's Docker image on Fly.io as a long-running Firecracker microVM, with secrets, an internal port, and migrate-on-boot.
Self-hosting with Docker
Build and run the node deploy target as a long-running container from its multi-stage Dockerfile, with a database and cache you provision yourself.