Deploying NestJS on a Shared VPS: How a Misplaced .env File Caused 500 Errors and 3‑Minute Ties Up Your Server—Fix It Now!
Imagine you’ve just pushed a brand‑new NestJS micro‑service to your cheap shared VPS. You hit “refresh” and the browser spits out a generic “500 Internal Server Error”. Your logs are flooded, the CPU spikes, and the entire server hangs for minutes. The cause? A .env file sitting in the wrong directory.
Why This Matters
Most developers treat environment files like a nice‑to‑have accessory. On a shared VPS, a misplaced .env can:
- Trigger endless restart loops for
pm2ornode - Consume CPU cycles, choking out other sites on the same server
- Expose secrets to the world if the file becomes publicly readable
- Cost you precious downtime and potentially angry clients
Step‑by‑Step Fix (No More 500s)
- Log into your VPS. Use SSH and navigate to the root of your NestJS project.
ssh user@your-vps-ip cd /var/www/nest-app - Check where the .env lives. By default NestJS expects it at the project root, but many tutorials copy it into
src/ordist/.ls -a - Move the file to the correct location. If you find
src/.envordist/.env, pull it up.mv src/.env . # or mv dist/.env . - Secure the file. Set permissions so only the app user can read it.
chmod 600 .env chown www-data:www-data .env # replace www-data with your app user - Update your process manager. If you’re using
pm2, tell it where the env file lives.pm2 start dist/main.js --name nest-app --env production --interpreter-options="-r dotenv/config" - Restart the service. Flush any lingering processes that might be stuck.
pm2 restart nest-app pm2 save - Verify the fix. Browse to your app, check
pm2 logs, and confirm the CPU drops below a percent.pm2 logs nest-app
Tip: Add a post‑deployment script that automatically verifies .env placement before starting the app. It saves you from accidental human error.
Code Example: Loading .env the Right Way
// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as dotenv from 'dotenv';
dotenv.config({ path: '.env' }); // explicit path prevents surprises
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(process.env.PORT || 3000);
}
bootstrap();
Real‑World Use Case
Acme SaaS runs 12 micro‑services on a single 2‑CPU shared VPS to keep costs under $15/mo. One weekend a junior dev accidentally committed a .env inside dist/. Within minutes the server’s load hit 100 %, the SaaS dashboard timed out, and customers were billed for “service unavailable”. By moving the file, resetting permissions, and adding a pre‑flight check, Acme cut downtime from 3 minutes to zero and saved an estimated $250 in lost revenue per incident.
Results / Outcome
- Server CPU stabilized under 2 % after the fix.
- All 500 errors vanished within seconds of restart.
- Security hardened – the .env is now invisible to the web root.
- Team confidence increased; the new script catches misplaced files during CI.
Bonus Tips to Keep Your VPS Happy
- Use a .env.example. Commit a template without secrets; developers copy it locally.
- Automate with a Bash guard.
#!/bin/bash if [ ! -f .env ]; then echo "❌ .env missing – aborting deployment" exit 1 fi # continue with build… - Monitor CPU spikes. Simple
topor a free service like UptimeRobot will alert you before a 3‑minute tie‑up. - Separate environments. Use Docker containers or at least different system users for each app on a shared VPS.
Warning: Never expose your .env file via the web server. A single misconfiguration (e.g., Options +Indexes) can dump all your API keys to the world.
Monetize Your Knowledge
If you found this guide helpful, consider turning it into a paid cheat sheet or a short video tutorial. Developers on platforms like Udemy or Gumroad love step‑by‑step crash courses that solve real server headaches. Plus, you can bundle a custom deploy.sh script and charge a one‑time fee.
“Fixing the .env location saved my client from a $300 downtime bill. The simple checklist below is now part of every deployment I do.” – Mike, Freelance DevOps Engineer
© 2026 Your Blog Name – All rights reserved.
No comments:
Post a Comment