دليل النشر

نشر تطبيق Node.js على VPS

انشر على VPS Cloud ←

دليل عملي

التطوير

نشر تطبيق Node.js على VPS

يتطلّب تشغيل تطبيق Node.js في بيئة الإنتاج أكثر من مجرّد `node app.js`: تحتاج إلى مدير عمليات يعيد تشغيله بعد أيّ انهيار، ومتغيّرات بيئة محفوظة خارج الشيفرة، ووكيل عكسي لـ HTTPS، وسجلّات لا تملأ القرص، وتشغيل تلقائي عند الإقلاع. على VPS تتحكّم في كل حلقة من هذه السلسلة، على عكس منصة مُدارة تحاسبك حسب الاستهلاك. ينطلق هذا الدليل من خادم Ubuntu، فارغًا كان أو مُجهَّزًا بقالب Node.js Stack، ويصل بك إلى التحديثات دون انقطاع.

8 دقائق للقراءةعدد الخطوات: 7
المحتويات· لماذا تنشر Node.js على VPS بدلًا من منصة مُدارة؟1/8
  1. 01لماذا تنشر Node.js على VPS بدلًا من منصة مُدارة؟
  2. 02ما الذي تكسبه مع VPS لتشغيل Node.js
  3. 03المتطلبات المسبقة
  4. 04الانطلاق من قالب Node.js Stack
  5. 05نشر تطبيق Node.js في الإنتاج
  6. 06توحيد الإعداد في ecosystem.config.js
  7. 07السجلّات: قراءتها ثم تدويرها
  8. 08التوثيق الرسمي

لماذا تنشر Node.js على VPS بدلًا من منصة مُدارة؟

منصات serverless وPaaS عملية في البداية، لكن كلفتها ترتفع مع حجم الزيارات، وهي تفرض قيودًا مثل المهل الزمنية (timeouts) والإقلاع البارد (cold starts) وحدود اتصالات WebSocket. يمنحك VPS عملية Node.js دائمة، واتصالات طويلة (WebSocket وSSE) بلا حدود مصطنعة، وموارد مخصّصة، وكلفة ثابتة يمكن توقّعها. أنت من يختار إصدار Node ومدير العمليات والوكيل العكسي واستراتيجية التحديث، دون الارتهان لأعراف مزوّد بعينه.

يتيح النموذج غير المتزامن وغير الحاجب في Node.js لعملية واحدة أن تتعامل مع عدد كبير من الاتصالات المتزامنة، وهذا ما يجعله خيارًا مناسبًا لواجهات REST والتطبيقات الآنية والخدمات المصغّرة، بشرط أن تبقى العملية حيّة. وهذا بالضبط ما ترفضه أغلب الاستضافات المشتركة حين تمنع العمليات الدائمة أو WebSocket. على VPS لا تُشارَك اعتماديات npm ولا متغيّرات البيئة ولا إعدادات PM2 مع أيّ حساب آخر.

ما الذي تكسبه مع VPS لتشغيل Node.js

  • عملية Node.js دائمة، مثالية لـ WebSocket وSSE والمهام الطويلة دون إقلاع بارد
  • إعادة تشغيل تلقائية بعد الانهيار وعند إعادة إقلاع الخادم بفضل PM2
  • وضع cluster لاستغلال كل أنوية المعالج في VPS دون تعديل شيفرتك
  • وكيل عكسي Nginx أمام Node لتولّي HTTPS والضغط والملفات الثابتة
  • عمّال طوابير (BullMQ وAgenda) ومهام مجدولة تعمل بجوار الواجهة البرمجية على الجهاز نفسه
  • عدّة تطبيقات على VPS واحد، لكلّ منها منفذ داخلي (3000 و3001…) ونطاق فرعي خلف Nginx
  • تصيير من جهة الخادم لأطر مثل Nuxt أو Next.js، يقدّمه الأساس نفسه من Node.js وPM2
  • كلفة ثابتة يمكن توقّعها، بلا فوترة لكل طلب ولا مفاجآت عند التوسّع
  • تحكّم كامل في إصدار Node.js واعتماديات النظام

المتطلبات المسبقة

يعمل تطبيق Node.js قياسي (واجهة Express أو Nest أو Fastify) براحة على VPS بمعالج أو معالجين افتراضيين و1 إلى 2 غيغابايت من الذاكرة؛ خطّط لذاكرة أكبر إن كنت تبني واجهة أمامية ثقيلة أثناء البناء أو تشغّل عمّالًا. استهدف 2 vCPU و2 غيغابايت حين تتقاسم الواجهة البرمجية الجهاز مع تصيير SSR أو قاعدة PostgreSQL.

اختر خطّ LTS ما زال مدعومًا: لم يعد Node.js 20 يتلقّى إصلاحات منذ 30 أبريل 2026، وانتقل Node.js 24 إلى مرحلة الصيانة في 20 أكتوبر 2026، وصار Node.js 26 هو إصدار LTS النشط منذ 28 أكتوبر 2026. ثبّته عبر nvm أو مستودع NodeSource لتثبيت الإصدار، مع PM2 مديرًا للعمليات وNginx وكيلًا عكسيًا. تحتاج إلى نطاق يشير إلى عنوان IP الخاص بـ VPS وإلى فتح المنفذين 80/443.

الانطلاق من قالب Node.js Stack

يجهّز قالب Node.js Stack في Marketplace الخاص بـ ServOrbit خادم VPS بنظام Ubuntu 24.04 مع Node.js من خطّ LTS الحالي في مستودع NodeSource، وnpm، وPM2 مثبّتًا على مستوى النظام، وNginx، وPostgreSQL. يعفيك القالب من الخطوة الأولى أدناه، ويبقى باقي الدليل صالحًا كما هو.

ليس هذا تطبيقًا بشاشة تسجيل دخول بل بيئة تشغيل: تدخلها عبر SSH ‏(ssh root@<vps-ip>) لرفع شيفرتك. عند الدخول الأول يعرض Nginx صفحة الترحيب الافتراضية على المنفذ 80، لأنه لم يُكتب بعد أيّ virtual host لنطاقك، كما أن Certbot غير مثبّت: تبقى خطوتا Nginx وHTTPS عليك. لا يستمع PostgreSQL إلا محليًا، ويصادق على مستخدم النظام postgres بطريقة peer: يفتح الأمر sudo -u postgres psql الطرفية دون كلمة مرور.

نشر تطبيق Node.js في الإنتاج

  1. تجهيز VPS وتثبيت Node.js

    على VPS بنظام Ubuntu 24.04، حدّث النظام وثبّت إصدار LTS من Node عبر nvm ‏(nvm install --lts) أو مستودع NodeSource. تحقّق بالأمرين node -v وnpm -v. أنشئ مستخدمًا غير root مخصّصًا للتطبيق بدل تشغيل كل شيء بصلاحيات root: هذا المستخدم هو من سيملك الشيفرة وملف .env وعمليات PM2. مع قالب Node.js Stack تكون Node.js وnpm وPM2 مثبّتة مسبقًا، فلا يبقى إلا إنشاء المستخدم.

  2. جلب الشيفرة والبناء

    استنسخ مستودعك على VPS، وثبّت اعتماديات الإنتاج (npm ci --omit=dev)، ثم شغّل البناء إن لزم (npm run build).

    ضع المتغيّرات الحسّاسة في ملف .env غير مُودَع في Git، لا يقرؤه إلا مستخدم التطبيق (chmod 600 .env). لا حاجة إلى مكتبة لقراءته: منذ Node.js 20.6 يحمّل الخيار --env-file هذا الملف في process.env عند الإقلاع.

  3. تجهيز قاعدة PostgreSQL

    إن احتاج التطبيق إلى قاعدة بيانات، فأنشئ دورًا وقاعدة مخصّصين بدل العمل بالمستخدم الخارق:

    sudo -u postgres createuser --pwprompt monapp
    sudo -u postgres createdb --owner=monapp monapp

    ثم اضبط DATABASE_URL=postgres://monapp:<password>@127.0.0.1:5432/monapp في ملف .env. وبما أن PostgreSQL لا يستمع إلا محليًا، فلا حاجة إلى فتح أيّ منفذ لقاعدة البيانات في الجدار الناري.

  4. تشغيل التطبيق باستخدام PM2

    ثبّت PM2 على مستوى النظام (npm install -g pm2، وهو مثبّت مسبقًا في القالب)، ثم شغّل التطبيق من مجلّد المشروع مع مطالبة Node بتحميل ملف .env:

    pm2 start app.js --name monapp -i max --node-args="--env-file=.env"

    يفعّل الخيار -i max وضع cluster على كل الأنوية، ويعيد PM2 تشغيل العملية تلقائيًا عند انهيارها.

  5. تفعيل التشغيل التلقائي عند الإقلاع

    ولّد سكربت systemd بالأمر pm2 startup منفّذًا بحساب مستخدم التطبيق، ثم نفّذ بصلاحيات sudo الأمر الذي يعرضه، وبعدها ثبّت الحالة الراهنة بالأمر pm2 save. عند إعادة إقلاع VPS التالية سيُعاد تشغيل تطبيقك تلقائيًا دون أيّ تدخّل.

  6. إعداد Nginx وكيلًا عكسيًا

    ثبّت Nginx إن لم يكن موجودًا، وأنشئ الملف /etc/nginx/sites-available/monapp، وهو virtual host يمرّر الطلبات إلى منفذ Node المحلي. الترويستان Upgrade وConnection مخصّصتان لـ WebSocket، أما X-Forwarded-Proto فتُعلم التطبيق بأن العميل يتّصل عبر HTTPS:

    server {
        listen 80;
        server_name yourdomain.com;
    
        location / {
            proxy_pass http://127.0.0.1:3000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }

    فعّل الموقع، واحذف الصفحة الافتراضية، واختبر الإعداد، ثم أعد التحميل:

    ln -s /etc/nginx/sites-available/monapp /etc/nginx/sites-enabled/
    rm /etc/nginx/sites-enabled/default
    nginx -t && systemctl reload nginx
  7. التأمين بـ HTTPS عبر Let's Encrypt

    ثبّت Certbot وإضافته الخاصة بـ Nginx، ثم اطلب الشهادة:

    apt install certbot python3-certbot-nginx
    certbot --nginx -d yourdomain.com

    يحصل Certbot على الشهادة، ويضبط التحويل من HTTP إلى HTTPS، ويجدول التجديد التلقائي. صار تطبيق Node يُقدَّم الآن عبر HTTPS.

توحيد الإعداد في ecosystem.config.js

حين يستضيف VPS أكثر من تطبيق، أو حين ترافق الواجهةَ البرمجية عمليةُ عامل، يصعب تتبّع الخيارات المُمرَّرة في سطر الأوامر. يقرأ PM2 ملف ecosystem.config.js الذي يصف كل عملية: السكربت، والمجلّد، وعدد النسخ، وحدّ الذاكرة، والمتغيّرات غير الحسّاسة.

module.exports = {
  apps: [
    {
      name: 'api',
      cwd: '/home/monapp/app',
      script: 'app.js',
      instances: 'max',
      exec_mode: 'cluster',
      node_args: '--env-file=.env',
      max_memory_restart: '500M',
      env: { NODE_ENV: 'production', PORT: 3000 }
    },
    {
      name: 'worker',
      cwd: '/home/monapp/app',
      script: 'worker.js',
      node_args: '--env-file=.env'
    }
  ]
}

يشغّل الأمر pm2 start ecosystem.config.js الكل، ويحدّثه pm2 reload ecosystem.config.js، ويستهدف الخيار --only api تطبيقًا واحدًا. تعمل الواجهة البرمجية هنا في وضع cluster على كل الأنوية، والعامل في عملية واحدة. أودِع هذا الملف في المستودع مع الشيفرة، أما الأسرار فتبقى في ملف .env خارج المستودع.

السجلّات: قراءتها ثم تدويرها

يلتقط PM2 المخرجات القياسية ومخرجات الأخطاء لكل عملية في ~/.pm2/logs/، بملف -out.log وملف -error.log لكل تطبيق. يتابعها الأمر pm2 logs monapp مباشرة، ويعرض pm2 logs monapp --lines 100 آخر الأسطر.

من دون تدوير تكبر هذه الملفات حتى يمتلئ القرص. تتكفّل الوحدة pm2-logrotate بذلك؛ فهي افتراضيًا تدوّر الملف بعد 10 ميغابايت وتحتفظ بثلاثين نسخة، وهي عتبات يسهل تعديلها:

pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 50M
pm2 set pm2-logrotate:retain 7

من جهة الوكيل، يظهر خطأ 502 في /var/log/nginx/error.log، وهو يعني في الغالب أن عملية Node.js متوقّفة أو أنها تستمع على منفذ غير المذكور في proxy_pass.

لعمليات نشر دون انقطاع، اجمع بين وضع cluster في PM2 والأمر pm2 reload monapp بدل restart: يعيد PM2 تشغيل العمّال واحدًا تلو الآخر، فتبقى نسخة واحدة على الأقل متاحة طوال التحديث. راقب بعد ذلك الذاكرة بالأمر pm2 monit، واضبط حدًّا لإعادة التشغيل التلقائي (--max-memory-restart 500M) للوقاية من تسرّب الذاكرة في الإنتاج.

التوثيق الرسمي

للخيارات الخاصة بكل أداة وتغييرات الإصدارات، ارجع إلى التوثيق الرسمي لـ Node.js، وإلى جدول إصدارات LTS في Node.js، وإلى توثيق PM2. يغطّي هذا الدليل وضع التطبيق في الإنتاج على VPS، ويبقى توثيق الناشر المرجع في الضبط الدقيق.

ضع تطبيق Node.js الخاص بك في الإنتاج على VPS سحابي

انشر VPS سحابيًا من ServOrbit مع قالب التطوير: Node.js وPM2 وNginx مُهيّأة مسبقًا لنقل تطبيقك إلى الإنتاج عبر HTTPS.