مرکزی مواد پر جائیں

PM2 Process Management for Node.js in Production

PM2 process management for Node.js production: ecosystem file configuration, zero-downtime restarts, log management, monitoring, clustering, and deployment workflows.

E
ECOSIRE Research and Development Team
|19 مارچ، 202612 منٹ پڑھیں2.2k الفاظ|

پیداوار میں Node.js کے لیے # PM2 پروسیس مینجمنٹ

جب آپ کی Node.js ایپلیکیشن صبح 2 بجے کریش ہو جاتی ہے، PM2 اس کے خود بخود دوبارہ شروع ہونے اور آپ کے بیدار ہونے تک آپ کے صارفین کو خالی صفحہ دیکھنے میں فرق ہے۔ PM2 ایک جنگی تجربہ شدہ پروسیس مینیجر ہے جو خود کار طریقے سے دوبارہ شروع ہونے، ملٹی کور استعمال کے لیے کلسٹرنگ، لاگ ایگریگیشن، اور زیرو ڈاؤن ٹائم ڈیپلائیز کو ہینڈل کرتا ہے - یہ سب ایک ہی کنفیگریشن فائل کے ساتھ جو آپ کے ذخیرے میں رہتی ہے۔

یہ گائیڈ ایک پروڈکشن PM2 سیٹ اپ کا احاطہ کرتا ہے جو بیک وقت 5 Node.js پراسیسز کا انتظام کرتا ہے: Next.js (فرنٹ اینڈ)، NestJS (API)، Docusaurus (docs) اور دو برانڈ سائٹس۔ پیٹرن واحد عمل کی تعیناتیوں پر یکساں طور پر لاگو ہوتے ہیں۔

اہم ٹیک ویز

  • ecosystem.config.cjs فائل (CommonJS، .js نہیں) ESMmodule اور CommonJS دونوں پروجیکٹوں کے ساتھ کام کرتی ہے
  • --update-env پرچم کی ضرورت ہوتی ہے جب نئے ماحول کے متغیرات کو لینے کے لیے دوبارہ شروع کیا جائے۔
  • .env.local کو اپ ڈیٹ کرنے کے بعد pm2 restart all کو --update-env کے بغیر کبھی استعمال نہ کریں
  • watch: false پروڈکشن میں - فائل دیکھنے سے تعمیراتی آؤٹ پٹس کے ساتھ لامحدود ری اسٹارٹ لوپس کا سبب بنتا ہے
  • max_memory_restart عمل کو مستقل طور پر ختم کیے بغیر خودکار میموری لیک سے تحفظ فراہم کرتا ہے۔
  • node_args: '--max-old-space-size=4096' میموری سے متعلق آپریشنز پر OOM کریشوں کو روکتا ہے۔
  • PM2 لاگز pm2-logrotate ماڈیول کے ساتھ گھومتے ہیں — اسے PM2 کے فوراً بعد انسٹال کریں۔
  • pm2 save اور pm2 startup سرور کے ریبوٹس پر آپ کے عمل کی فہرست کو برقرار رکھتے ہیں۔

انسٹالیشن

# Install PM2 globally
npm install -g pm2

# Install the log rotation module immediately
pm2 install pm2-logrotate

# Configure log rotation
pm2 set pm2-logrotate:max_size 50M
pm2 set pm2-logrotate:retain 7
pm2 set pm2-logrotate:compress true
pm2 set pm2-logrotate:dateFormat YYYY-MM-DD

ایکو سسٹم کنفیگریشن فائل

ecosystem.config.cjs فائل (ESM اور CJS دونوں پروجیکٹس کے ساتھ کام کرنے کے لیے CommonJS فارمیٹ) آپ کے تمام عمل کی وضاحت کرتی ہے:

// ecosystem.config.cjs
module.exports = {
  apps: [
    // ─── Next.js Frontend ────────────────────────────────────────────
    {
      name: 'ecosire-web',
      script: 'node_modules/.bin/next',
      args: 'start',
      cwd: '/opt/ecosire/app/apps/web',
      instances: 1,        // Single instance — Next.js handles its own multi-threading
      exec_mode: 'fork',
      env: {
        NODE_ENV: 'production',
        PORT: 3000,
      },
      // Memory management
      max_memory_restart: '1G',
      node_args: '--max-old-space-size=1024',
      // Logging
      out_file: '/var/log/pm2/ecosire-web.out.log',
      error_file: '/var/log/pm2/ecosire-web.err.log',
      merge_logs: true,
      log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
      // Restart behavior
      watch: false,
      restart_delay: 3000,
      max_restarts: 10,
      min_uptime: '30s',   // Must stay up 30s to count as successful start
      autorestart: true,
      // Graceful shutdown
      kill_timeout: 30000, // 30 seconds to shut down gracefully
      wait_ready: true,    // Wait for process.send('ready')
      listen_timeout: 60000,
    },

    // ─── NestJS API ──────────────────────────────────────────────────
    {
      name: 'ecosire-api',
      script: 'dist/main.js',
      cwd: '/opt/ecosire/app/apps/api',
      instances: 2,         // Cluster mode for multi-core utilization
      exec_mode: 'cluster',
      env: {
        NODE_ENV: 'production',
        PORT: 3001,
      },
      max_memory_restart: '512M',
      node_args: '--max-old-space-size=512',
      out_file: '/var/log/pm2/ecosire-api.out.log',
      error_file: '/var/log/pm2/ecosire-api.err.log',
      merge_logs: true,
      log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
      watch: false,
      restart_delay: 2000,
      max_restarts: 10,
      min_uptime: '20s',
      autorestart: true,
      kill_timeout: 15000,
      // Graceful cluster reload support
      listen_timeout: 30000,
    },

    // ─── Docusaurus Docs ─────────────────────────────────────────────
    {
      name: 'ecosire-docs',
      script: 'node_modules/.bin/docusaurus',
      args: 'serve',
      cwd: '/opt/ecosire/app/apps/docs',
      instances: 1,
      exec_mode: 'fork',
      env: {
        NODE_ENV: 'production',
        PORT: 3002,
      },
      max_memory_restart: '256M',
      out_file: '/var/log/pm2/ecosire-docs.out.log',
      error_file: '/var/log/pm2/ecosire-docs.err.log',
      merge_logs: true,
      log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
      watch: false,
      restart_delay: 3000,
      max_restarts: 5,
      min_uptime: '30s',
      autorestart: true,
      kill_timeout: 10000,
    },

    // ─── Brand Site: Odovation ───────────────────────────────────────
    {
      name: 'odovation-web',
      script: 'node_modules/.bin/next',
      args: 'start',
      cwd: '/opt/ecosire/app/apps/odovation',
      instances: 1,
      exec_mode: 'fork',
      env: {
        NODE_ENV: 'production',
        PORT: 3010,
      },
      max_memory_restart: '512M',
      out_file: '/var/log/pm2/odovation-web.out.log',
      error_file: '/var/log/pm2/odovation-web.err.log',
      merge_logs: true,
      log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
      watch: false,
      restart_delay: 3000,
      max_restarts: 10,
      min_uptime: '30s',
      autorestart: true,
    },

    // ─── Brand Site: MuhammadAmir ────────────────────────────────────
    {
      name: 'muhammadamir-web',
      script: 'node_modules/.bin/next',
      args: 'start',
      cwd: '/opt/ecosire/app/apps/muhammadamir',
      instances: 1,
      exec_mode: 'fork',
      env: {
        NODE_ENV: 'production',
        PORT: 3020,
      },
      max_memory_restart: '512M',
      out_file: '/var/log/pm2/muhammadamir-web.out.log',
      error_file: '/var/log/pm2/muhammadamir-web.err.log',
      merge_logs: true,
      log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
      watch: false,
      restart_delay: 3000,
      max_restarts: 10,
      min_uptime: '30s',
      autorestart: true,
    },
  ],
};

کور PM2 کمانڈز

# Start all processes from ecosystem file
pm2 start ecosystem.config.cjs

# Restart all (with updated environment variables)
pm2 restart ecosystem.config.cjs --update-env

# Graceful reload (zero-downtime for cluster mode)
pm2 reload ecosystem.config.cjs

# Stop all processes
pm2 stop all

# Delete all processes from PM2 registry
pm2 delete all

# Individual process management
pm2 restart ecosire-api
pm2 stop ecosire-docs
pm2 logs ecosire-web --lines 100

# Real-time monitoring dashboard
pm2 monit

# Status overview
pm2 status
pm2 list

سرور ریبوٹ پر اسٹارٹ اپ

سٹارٹ اپ کنفیگریشن کے بغیر، سرور ریبوٹ پر PM2 کے تمام عمل ضائع ہو جاتے ہیں:

# Generate and install the startup script for your init system
pm2 startup
# Copy the output command and run it (it looks like:)
# sudo env PATH=$PATH:/usr/bin pm2 startup systemd -u ubuntu --hp /home/ubuntu

# Save the current process list
pm2 save
# This creates ~/.pm2/dump.pm2 — processes are restored on reboot

# Verify startup works
pm2 resurrect  # Manually restore from dump.pm2

جب بھی آپ عمل کو شامل یا ہٹاتے ہیں، ڈمپ فائل کو اپ ڈیٹ کرنے کے لیے pm2 save کو دوبارہ چلائیں۔


زیرو-ڈاؤن ٹائم تعیناتیاں

کلسٹر موڈ میں NestJS کے لیے، PM2 حقیقی صفر ڈاؤن ٹائم ری لوڈز کو سپورٹ کرتا ہے:

# Reload restarts workers one at a time (zero-downtime)
# Old workers handle requests while new ones start
pm2 reload ecosire-api

# vs restart — kills all workers simultaneously (brief downtime)
pm2 restart ecosire-api

Next.js کے لیے (جو فورک موڈ میں چلتا ہے، واحد مثال)، صفر-ڈاؤن ٹائم ایک مختلف نقطہ نظر کی ضرورت ہے۔ اپنی ایپ سے اسٹارٹ اپ سگنل کے ساتھ wait_ready + listen_timeout کنفیگریشن استعمال کریں:

// apps/web — this is handled automatically by Next.js
// But for NestJS, send the ready signal explicitly:

// apps/api/src/main.ts
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3001);

  // Signal PM2 that the process is ready
  if (process.send) {
    process.send('ready');
  }
}

bootstrap();

لاگ مینجمنٹ

PM2 لاگز آپ کی ڈسک کو بھر سکتے ہیں اگر انتظام نہ کیا جائے۔ لاگ گردش کو فوری طور پر ترتیب دیں:

# Install log rotation module
pm2 install pm2-logrotate

# Configuration
pm2 set pm2-logrotate:max_size 50M       # Rotate when log reaches 50MB
pm2 set pm2-logrotate:retain 7           # Keep 7 days of logs
pm2 set pm2-logrotate:compress true      # Gzip rotated logs
pm2 set pm2-logrotate:dateFormat YYYY-MM-DD
pm2 set pm2-logrotate:workerInterval 30  # Check rotation interval (seconds)
pm2 set pm2-logrotate:rotateInterval '0 0 * * *'  # Daily at midnight

مفید لاگ کمانڈز:

# View all logs combined
pm2 logs

# View specific process logs
pm2 logs ecosire-api

# View with timestamps
pm2 logs --timestamp

# Flush all log files
pm2 flush

# Tail error logs only
pm2 logs ecosire-api --err --lines 200

مانیٹرنگ اور میٹرکس

PM2 Plus (سابقہ ​​Keymetrics) کلاؤڈ بیسڈ مانیٹرنگ فراہم کرتا ہے۔ خود میزبان نگرانی کے لیے:

# Built-in terminal dashboard
pm2 monit

# Get JSON status for scripting/monitoring integration
pm2 jlist    # JSON process list
pm2 prettylist  # Formatted process list

# Integrate with your monitoring stack
pm2 set pm2-server-monit:interval 5  # Metrics collection interval

پروڈکشن مانیٹرنگ کے لیے، PM2 میٹرکس کو Prometheus پر ظاہر کریں:

npm install -g pm2-prometheus-exporter
pm2 set pm2-prometheus-exporter:port 9209

# Scrape in Prometheus config:
# - job_name: pm2
#   static_configs:
#     - targets: ['localhost:9209']

تعیناتی اسکرپٹ انٹیگریشن

ایک عام تعیناتی ترتیب:

#!/bin/bash
# scripts/deploy-production.sh

set -e

echo "=== Starting deployment ==="

# 1. Pull latest code
git pull origin main

# 2. Install dependencies
pnpm install --frozen-lockfile

# 3. Build all apps (with Turbo remote cache)
TURBO_TOKEN="$TURBO_TOKEN" TURBO_TEAM="$TURBO_TEAM" \
  npx turbo run build

# 4. Run database migrations
pnpm --filter @ecosire/db db:migrate

# 5. Restart PM2 processes
# --update-env picks up changes in .env.local
pm2 restart ecosystem.config.cjs --update-env

# 6. Wait for processes to stabilize
sleep 10

# 7. Health checks
curl -f https://ecosire.com/ -o /dev/null -s || {
  echo "Web health check failed — rolling back"
  git revert HEAD --no-edit
  pm2 restart ecosystem.config.cjs --update-env
  exit 1
}

curl -f https://api.ecosire.com/api/health -o /dev/null -s || {
  echo "API health check failed — rolling back"
  git revert HEAD --no-edit
  pm2 restart ecosystem.config.cjs --update-env
  exit 1
}

# 8. Save process state
pm2 save

echo "=== Deployment complete ==="

مشترکہ نقصانات اور حل

خطرہ 1: بھول جانا --update-env

.env.local کو اپ ڈیٹ کرنے کے بعد، pm2 restart all کو --update-env کے بغیر چلانے سے پرانے ماحولیاتی متغیرات کے ساتھ عمل دوبارہ شروع ہوتا ہے۔ ہمیشہ pm2 restart ecosystem.config.cjs --update-env استعمال کریں۔

خطرہ 2: پیداوار میں watch: true کا استعمال

watch: true اس عمل کو دوبارہ شروع کرتا ہے جب کوئی فائل تبدیل ہوتی ہے۔ پروڈکشن میں، آؤٹ پٹ ہر تعیناتی کو تبدیل کرتا ہے - یہ لامحدود ری اسٹارٹ لوپس کا سبب بنتا ہے۔ ہمیشہ watch: false سیٹ کریں۔

خطرہ 3: خوبصورت شٹ ڈاؤن کے لیے SIGTERM کو ہینڈل نہیں کرنا

PM2 دوبارہ شروع/روکتے وقت SIGTERM بھیجتا ہے۔ اگر آپ کی ایپ اسے ہینڈل نہیں کرتی ہے، تو PM2 kill_timeout ملی سیکنڈ انتظار کرتا ہے اور SIGKILL بھیجتا ہے — جس کی وجہ سے درخواستیں ضائع ہو سکتی ہیں۔ NestJS میں SIGTERM کو ہینڈل کریں:

// main.ts
const app = await NestFactory.create(AppModule);
await app.listen(3001);

// Graceful shutdown
process.on('SIGTERM', async () => {
  await app.close();
  process.exit(0);
});

خطرہ 4: PM2 لاگ ڈسک کی جگہ ختم ہو رہی ہے

pm2-logrotate کے بغیر، PM2 لاگس غیر معینہ مدت تک بڑھتے ہیں۔ ایک بہت زیادہ اسمگل شدہ API روزانہ گیگا بائٹس لاگ تیار کر سکتا ہے۔ pm2-logrotate کو فوری طور پر انسٹال کریں اور ایک معقول max_size (50MB) اور retain (7 دن) سیٹ کریں۔

خطرہ 5: ریبوٹ کے بعد عمل کو کھونا

pm2 start تمام ریبوٹس کے عمل کو برقرار نہیں رکھتا ہے۔ ابتدائی سیٹ اپ کے بعد ہمیشہ pm2 startup + pm2 save چلائیں۔ اگر ریبوٹ کے بعد عمل غائب ہو جائیں تو محفوظ شدہ ڈمپ سے بحال کرنے کے لیے pm2 resurrect چلائیں۔


اکثر پوچھے گئے سوالات

مجھے کلسٹر موڈ بمقابلہ فورک موڈ کب استعمال کرنا چاہئے؟

CPU کے پابند کام کے بوجھ کے لیے کلسٹر وضع کا استعمال کریں (بھاری کمپیوٹیشن، ڈیٹا پروسیسنگ کے ساتھ NestJS APIs)۔ کلسٹر موڈ instances ورکر پروسیسز اور ان کے درمیان PM2 لوڈ بیلنس پیدا کرتا ہے — تمام CPU کور کا فائدہ اٹھاتے ہوئے۔ I/O-باؤنڈ ورک بوجھ (Next.js، سٹیٹک فائل سرونگ) کے لیے فورک موڈ استعمال کریں یا جب عمل کلسٹرنگ کو سپورٹ نہیں کرتا ہے (سنگل تھریڈڈ اسکرپٹس، Docusaurus serve)۔ Next.js اپنے ورکر تھریڈز کو اندرونی طور پر ہینڈل کرتا ہے، لہذا instances: 1 کے ساتھ فورک موڈ درست ہے۔

میں PM2 کو ڈاکر کنٹینر میں کیسے چلا سکتا ہوں؟

ڈاکر میں PM2 سگنلز کو درست طریقے سے ہینڈل کرنے کے لیے pm2 کی بجائے pm2-docker (یا pm2-runtime) استعمال کرتا ہے۔ رن ٹائم ورژن ڈیمونائز نہیں کرتا ہے (جس کی وجہ سے ڈوکر باہر نکل جائے گا)، صحیح طریقے سے سگنلز کو چائلڈ پروسیسز میں بھیجتا ہے، اور فائلوں کی بجائے stdout/stderr پر لاگ ان کرتا ہے۔ اپنی Dockerfile میں CMD ["pm2-runtime", "ecosystem.config.cjs"] استعمال کریں۔

میں ریموٹ مشین سے PM2 کے عمل کی نگرانی کیسے کروں؟

پی ایم 2 پلس (پے فی پروسیس کلاؤڈ سروس) ایک ویب ڈیش بورڈ فراہم کرتا ہے۔ خود میزبانی کی نگرانی کے لیے، PM2 کے میٹرکس کو Prometheus برآمد کنندہ کے ذریعے بے نقاب کریں اور Grafana میں تصور کریں۔ سادہ حیثیت کی جانچ کے لیے، آپ SSH اور pm2 status کو چلا سکتے ہیں، یا HTTP اینڈ پوائنٹ کے ذریعے میٹرکس کو بے نقاب کر سکتے ہیں جسے آپ کا مانیٹرنگ سسٹم پول کرتا ہے۔

pm2 ری لوڈ اور pm2 ری اسٹارٹ میں کیا فرق ہے؟

pm2 restart تمام کارکنوں کو بیک وقت مارتا ہے اور انہیں دوبارہ شروع کرتا ہے — ایک مختصر مدت ہے جس میں کارکن نہیں چل رہے ہیں (ڈاؤن ٹائم)۔ pm2 reload خوبصورت ہے: یہ نئے کارکنوں کو شروع کرتا ہے، ان کے تیار ہونے کا انتظار کرتا ہے، پھر پرانے کارکنوں کو بند کر دیتا ہے — صفر ڈاؤن ٹائم۔ پیداوار کی تعیناتیوں کے لیے pm2 reload استعمال کریں۔ نوٹ: دوبارہ لوڈ صرف کلسٹر موڈ میں صحیح طریقے سے کام کرتا ہے۔ فورک موڈ رویے کو دوبارہ شروع کرنے پر واپس آتا ہے۔

مختلف عملوں کے لیے میں مختلف ماحولیاتی متغیرات کیسے ترتیب دوں؟

ecosystem.config.cjs میں ہر عمل کے اپنے env اور env_production حصے ہوتے ہیں۔ env_production سیکشن استعمال ہوتا ہے جب آپ --env production کو PM2 کمانڈز پاس کرتے ہیں۔ راز کے لیے، انہیں کبھی بھی براہ راست ایکو سسٹم فائل میں نہ ڈالیں — انہیں سسٹم کے ماحول یا .env.local فائل میں سیٹ کریں اور PM2 کو ان کا وارث ہونے دیں۔ --update-env پرچم اس بات کو یقینی بناتا ہے کہ PM2 دوبارہ شروع ہونے پر ماحولیاتی متغیرات کو دوبارہ پڑھتا ہے۔


اگلے اقدامات

PM2 کسی بھی پروڈکشن Node.js کی تعیناتی کا ایک بنیادی حصہ ہے۔ ECOSIRE پیداوار میں 5 PM2 پروسیسز کا انتظام کرتا ہے — Next.js، NestJS، Docusaurus، اور دو برانڈ سائٹس — کے ساتھ خودکار ری اسٹارٹ، لاگ روٹیشن، اور زیرو ڈاؤن ٹائم ڈیپلائمنٹس مین پر ہر دھکا پر۔

چاہے آپ کو DevOps انجینئرنگ سپورٹ، پروڈکشن ڈیپلائمنٹ آرکیٹیکچر، یا کنٹینرائزڈ سیٹ اپ میں منتقل ہونے میں مدد کی ضرورت ہو، یہ دیکھنے کے لیے کہ ہم کس طرح مدد کر سکتے ہیں، ہماری سروسز کو دریافت کریں۔

E

تحریر

ECOSIRE Research and Development Team

تکنیکی تحریر

ECOSIRE کی تکنیکی تحریر کی ٹیم Odoo ERP، Shopify ای کامرس، AI ایجنٹس، Power BI اینالیٹکس، GoHighLevel آٹومیشن اور انٹرپرائز سافٹ ویئر کے بہترین طریقوں پر لکھتی ہے۔ ہماری گائیڈز کاروباروں کو سوچ سمجھ کر ٹیکنالوجی کے فیصلے کرنے میں مدد دیتی ہیں۔

ECOSIRE

ECOSIRE کے ساتھ اپنا کاروبار بڑھائیں

ERP، ای کامرس، AI، تجزیات، اور آٹومیشن میں انٹرپرائز حل۔