Deploy NestJS | API with Postgres and No Required Secrets
NestJS 11 and Prisma 7 on Railway, deploys without any required secrets
Just deployed
Just deployed
/var/lib/postgresql/data
Deploy and Host a NestJS API on Railway
A NestJS 11 API on Prisma 7 and Postgres, with nothing to fill in before it deploys.
About Hosting NestJS
The NestJS template on Railway declares three variables with empty values - RESEND_API_KEY, JWT_ACCESS_SECRET and JWT_REFRESH_SECRET - and Railway turns every empty value into a required field. Before the Deploy button will light up you have to sign up for a third-party email service, obtain an API key, and invent two JWT secrets, for a starter you have not seen run yet. Its FRONTEND_URL also defaults to localhost:3000, which is wrong for every deployment. Fewer than one in ten come up.
This one deploys without asking anything. It ships no auth and no email, on purpose: a generic starter that implements neither should not be collecting their secrets. Add @nestjs/jwt and a mail provider when you need them, and the variables along with them.
Common Use Cases
- A structured API where modules, dependency injection and DTO validation are wanted from the start
- A backend for a front end hosted separately
- A service that will grow - the Nest layout is the point, and it is already correct here
Dependencies for NestJS Hosting
- Postgres, included in this template, on a persistent volume
- Nothing else.
Deployment Dependencies
- NestJS: https://docs.nestjs.com
- Prisma: https://www.prisma.io/docs
- Source: https://github.com/ak40u/nestjs-railway-starter
Implementation Details
| Method | Path | Does |
|---|---|---|
| GET | / | Lists the endpoints |
| GET | /health | Runs SELECT 1; reports degraded when Postgres is unreachable |
| GET | /notes | Last 100 notes, newest first |
| POST | /notes | Creates a note from {"body": "..."} |
Four decisions worth keeping:
- Migrations run in preDeployCommand, after the build and before the new version takes traffic. The build has no database to connect to.
- whitelist: true on the validation pipe strips properties the DTO does not declare, so a request cannot smuggle extra fields into a create call.
- enableShutdownHooks(). Railway sends SIGTERM before replacing a container; without it, in-flight requests are cut off on every deploy.
- The lockfile is committed and audited clean. @nestjs/cli pulls a vulnerable brace-expansion through its webpack plugin, and Railway refuses to build when the committed lockfile carries a HIGH advisory, so package.json overrides it forward. Run
npm audit --audit-level=highbefore pushing.
Prisma 7 also changed how connections are configured: url is no longer allowed in schema.prisma, the CLI reads it from prisma.config.ts, and the runtime gets it through a driver adapter.
Why Deploy NestJS on Railway?
Postgres, a private network and a domain from one deploy, migrations applied before each release takes traffic, and a deploy form that asks for nothing you do not have yet.
Template Content