GenerateSaaS

Render

Run the node deploy target on Render as a managed Web Service built from the Dockerfile or a Node build.

Render is managed cloud for long-running web services. It runs the standard node deploy target - there is no Render-specific code in the boilerplate, just the same Dockerfile or Node build you would run anywhere.

Render is one long-running host for the node target - like Fly.io, Railway, Coolify, or Dokploy. Pick node at generatesaas init; both fullstack and separate architectures work here.

Deploy

Create a Web Service. In the Render dashboard, pick New → Web Service and connect your repository.

Choose the runtime. Select Docker 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 if you prefer; the Dockerfile is the portable default.

Add environment variables. Set the required keys in the service's Environment tab (see the table below). They are validated at boot - the server throws if any are missing or malformed.

Attach a database and cache. Add a Render PostgreSQL instance (or any external DATABASE_URL). For the cache, the provider you chose at init decides the env vars: Redis (self-hosted) uses REDIS_URL (Render's own Key Value store fits here), while Upstash uses UPSTASH_REDIS_REST_URL + UPSTASH_REDIS_REST_TOKEN. See Caching & Rate Limiting.

Deploy. Render builds the image and runs CMD pnpm start. The schema step the CLI prepended to the owner's start script runs first, applying migrations before the server boots.

Use the TLS domain. Render issues a managed *.onrender.com URL with TLS, or you can attach a custom domain. Set that origin as API_URL / BASE_URL and add it to TRUSTED_ORIGINS.

Required environment variables

Set these on the service before the first deploy - validated at boot by @repo/runtime (packages/runtime/src/env.ts).

VariablePurpose
DATABASE_URLPostgres connection; required by the boot-time schema step
BETTER_AUTH_SECRETAuth signing secret (min 32 chars)
API_URLThe backend's public URL (your Render domain)
REDIS_URLCache connection - only on the self-hosted Redis variant. The Upstash variant uses UPSTASH_REDIS_REST_URL + UPSTASH_REDIS_REST_TOKEN instead
INNGEST_APP_IDBackground-jobs app identifier
INNGEST_EVENT_KEYBackground-jobs event key
INNGEST_BASE_URLBackground-jobs endpoint URL
TRUSTED_ORIGINSComma-separated production domains for CORS + Better Auth trusted origins

See Environment variables for the full list.

Database and cache options

In production you supply your own data services. Pick a Render-hosted option or point at an external managed provider.

The cache provider is fixed at init - set the env vars for that variant only, never both.

ServiceRender-hostedExternal managed
PostgresRender PostgreSQL → DATABASE_URLNeon or Supabase → DATABASE_URL
Cache (Redis variant)Render Key Value → REDIS_URLself-hosted Redis → REDIS_URL
Cache (Upstash variant)-Upstash → UPSTASH_REDIS_REST_URL + UPSTASH_REDIS_REST_TOKEN

Never pass --demo for a real deployment. The schema step becomes a destructive reset && push --force that wipes the database on every boot.

There is no pnpm infra step here - infra/docker-compose.yml is for local development only. On Render the database and cache are managed services you attach, not containers you start.

Next steps

On this page