Careeroza
pm2 and Environments
Running on a VM with pm2
On a plain Linux VM (GCP, AWS EC2, DigitalOcean), pm2 keeps the app running, restarts it on crash and can run one process per CPU core.
ecosystem.config.js
module.exports = {
apps: [
{
name: 'shopease-api',
script: 'dist/main.js',
instances: 'max', // one per CPU core
exec_mode: 'cluster',
max_memory_restart: '512M',
env_production: { NODE_ENV: 'production', PORT: 3000 },
env_staging: { NODE_ENV: 'production', PORT: 3100 },
},
],
};Example
npm ci && npm run build && npx prisma migrate deploy
pm2 start ecosystem.config.js --env production
pm2 statusExample output
[PM2] Starting /srv/shopease-api/dist/main.js in cluster_mode (4 instances) [PM2] Done. ┌────┬────────────────┬─────────┬──────┬────────┬────────┬──────────┐ │ id │ name │ mode │ ↺ │ status │ cpu │ memory │ ├────┼────────────────┼─────────┼──────┼────────┼────────┼──────────┤ │ 0 │ shopease-api │ cluster │ 0 │ online │ 0% │ 92.4mb │ │ 1 │ shopease-api │ cluster │ 0 │ online │ 0% │ 90.1mb │ │ 2 │ shopease-api │ cluster │ 0 │ online │ 0% │ 91.7mb │ │ 3 │ shopease-api │ cluster │ 0 │ online │ 0% │ 89.8mb │ └────┴────────────────┴─────────┴──────┴────────┴────────┴──────────┘
Tip: Use pm2 reload shopease-api for zero-downtime deploys (instances restart one by one), and put nginx in front for HTTPS and gzip.
One Build, Many Environments
| Setting | Development | Staging | Production |
|---|---|---|---|
| Source of config | .env.local | CI secrets | Secret manager |
| Database | Docker on laptop | Small managed DB | Managed DB with backups and replicas |
| Logs | Pretty text, debug | JSON, debug | JSON, info |
Swagger /docs | On | On | Off or behind auth |
| CORS origins | localhost | staging domain | shopease.in only |