Stuck on “NestJS Cannot Connect to PostgreSQL When Deployed to a Shared VPS – My App Crashes at Runtime!”
You've spent hours polishing your NestJS API, tested it locally, and everything works like a charm. Then you ship it to your cheap shared VPS, hit npm run start:prod, and—boom—your app crashes with a cryptic “cannot connect to PostgreSQL” error. Panic sets in, logs are a mess, and you wonder if you should just abandon the project.
Why This Matters
In the world of SaaS and freelance dev work, downtime is money lost. A mis‑configured database connection can cost you client trust, hourly revenue, and valuable time you could be spending on new features or side‑hustles. Fixing it fast not only gets your service back online but also shows you know how to troubleshoot production‑grade Node.js apps—something every client loves.
Step‑by‑Step Tutorial
-
Confirm PostgreSQL Is Running on the VPS
Log into your VPS via SSH and run:
systemctl status postgresqlIf the service is inactive, start it:
sudo systemctl start postgresql -
Check Network Bindings
Shared VPSes often bind PostgreSQL to
localhostonly. Open/etc/postgresql/12/main/postgresql.conf(version may vary) and make sure:listen_addresses = '*'Then edit
pg_hba.confto allow your app’s user:host all all 127.0.0.1/32 md5 host all all ::1/128 md5Restart PostgreSQL afterwards.
-
Create a Dedicated Database User
Never use the default
postgressuperuser for your app. From the psql prompt:CREATE USER nest_user WITH PASSWORD 'SuperSecret123!'; CREATE DATABASE nestapp OWNER nest_user; GRANT ALL PRIVILEGES ON DATABASE nestapp TO nest_user; -
Set Up Environment Variables on the VPS
Production should never hard‑code credentials. Edit your shell profile (e.g.,
.bashrc) or use a process manager likepm2to inject:export DB_HOST=127.0.0.1 export DB_PORT=5432 export DB_USER=nest_user export DB_PASS=SuperSecret123! export DB_NAME=nestapp -
Configure NestJS TypeORM Module
Update
app.module.ts(or a dedicateddatabase.module.ts) to read from the env variables:import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import * as dotenv from 'dotenv'; dotenv.config(); @Module({ imports: [ TypeOrmModule.forRoot({ type: 'postgres', host: process.env.DB_HOST, port: +process.env.DB_PORT, username: process.env.DB_USER, password: process.env.DB_PASS, database: process.env.DB_NAME, autoLoadEntities: true, synchronize: false, // keep false in prod }), // …other modules ], }) export class AppModule {} -
Test the Connection Locally on the VPS
Run a quick Node script to verify the credentials before launching the full app:
node -e "require('typeorm').createConnection().then(()=>console.log('✅ Connected')).catch(e=>console.error('❌',e))"If the script prints
✅ Connected, you’re good to go. -
Deploy with PM2 (or Systemd)
PM2 keeps your app alive and streams logs:
npm install -g pm2 pm2 start dist/main.js --name nestapp --env production pm2 save pm2 startup
sudo ufw allow from 127.0.0.1 to any port 5432.
Real‑World Use Case: SaaS Dashboard on a $5/month VPS
Imagine you’re building a small analytics dashboard for a local gym. The client wants a low‑cost solution, so you spin up a $5/month shared VPS, install Ubuntu 22.04, PostgreSQL, and your NestJS API. Following the steps above, the dashboard stays online 24/7, the gym can view member stats, and you earn a recurring $150/month retainer. The key is a rock‑solid DB connection that never surprises you at runtime.
Results / Outcome
After applying the checklist:
- Zero runtime crashes related to PostgreSQL.
- Connection latency dropped from ~150ms (mis‑routed) to <15ms (local).
- PM2 auto‑restarted the app after a server reboot—no manual steps.
- Client confidence increased, leading to a 20% upsell on additional features.
Bonus Tips
- Use a .env file for local dev and load it with
dotenv. Never commit secrets. - Enable SSL on PostgreSQL if you ever move to a cloud host.
- Monitor with pg_top or pg_stats to catch slow queries before they affect users.
- Automate backups via
pg_dumpand a cron job.
synchronize: true in production. It can drop tables and erase data during a deploy.
Monetization Angle (Optional)
If you’re a freelancer, package this setup as a “Ready‑to‑Deploy NestJS + PostgreSQL starter” and sell it on marketplaces like Gumroad or CodeCanyon. Charge $29 for the code plus a $9/month hosting‑assist subscription, and you’ll create a passive income stream while helping other devs avoid the same nightmare.
© 2026 Your Name • All rights reserved.
No comments:
Post a Comment