RDP Monster

استضافة بوت ديسكورد على VPS: أبقِه متصلاً 24/7

استضافة بوت ديسكورد على VPS: أبقِه متصلاً 24/7

لماذا يبقى بوت ديسكورد متصلاً فعلاً على خادم VPS

بوت ديسكورد ليس صفحة ويب. فبمجرد تسجيل الدخول يحافظ على اتصال WebSocket دائم ببوابة ديسكورد ويجب أن يردّ على نبضات الاتصال باستمرار؛ وحين تتوقف العملية يظهر البوت خارج الاتصال وتفشل كل الأوامر. هذا الشرط وحده، أي عملية لا تنام أبداً، يستبعد معظم الاستضافات «المجانية»:

  • Heroku ألغت خطط dynos المجانية في نوفمبر 2022.
  • Replit لم تعد تُبقي المشاريع المجانية قيد التشغيل؛ وانتقلت ميزة always-on إلى عمليات النشر المدفوعة.
  • Glitch أنهت استضافة التطبيقات لديها في 2025.
  • الخطط المجانية التي تنام بعد فترة خمول تقطع اتصال البوابة في كل مرة تتوقف فيها؛ وبالنسبة للمستخدمين يكون البوت ببساطة معطلاً.

استضافة بوت ديسكورد على خادم VPS تعالج المشكلة من جذرها: جهاز Linux بصلاحيات root يعمل على مدار الساعة، حيث يصبح البوت مجرد خدمة أخرى يديرها نظام التشغيل الأولي. يبني هذا الدليل ذلك على Ubuntu 24.04 (صالح كذلك لـ 22.04 وDebian 12) باستخدام discord.py وdiscord.js، ثم يتناول التعامل مع التوكن وإعادة التشغيل والسجلات والتحديثات والذاكرة.

تجهيز الخادم: مستخدم مخصص وبيئة تشغيل

أمّن الباب الأمامي أولاً: فعّل SSH على Ubuntu وقوّه بالمصادقة بالمفاتيح، ومنع دخول root، وufw. البوت يتصل خارجياً بديسكورد ولا يحتاج أي منفذ وارد، لذا يمكن أن يبقى الجدار الناري مغلقاً أمام كل شيء عدا SSH.

الخطوة 1: أنشئ حساباً بلا صلاحيات للبوت

sudo useradd -r -m -d /opt/mybot -s /usr/sbin/nologin bot

الحساب المخصص يعني أن بوتاً به خلل أو اعتمادية مخترقة من npm أو PyPI لن تستطيع قراءة مفاتيح SSH أو المساس بخدمات أخرى. كل شيء موجود في /opt/mybot، والمالك هو bot.

الخطوة 2 (Python): ثبّت discord.py في بيئة افتراضية

sudo apt update && sudo apt install -y python3 python3-venv python3-pip
sudo -u bot python3 -m venv /opt/mybot/.venv
sudo -u bot /opt/mybot/.venv/bin/pip install -U discord.py python-dotenv

يتطلب discord.py 2.x إصدار Python 3.8 أو أحدث؛ ويأتي Ubuntu 24.04 بالإصدار 3.12 و22.04 بالإصدار 3.10، لذا فإن مفسّر التوزيعة مناسب. أضف discord.py[voice] وffmpeg فقط إذا كنت تستخدم القنوات الصوتية.

الخطوة 3 (Node.js): ثبّت إصدار LTS حديثاً وdiscord.js

curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs
sudo -u bot bash -c 'cd /opt/mybot && npm init -y && npm install discord.js dotenv'

حزمة nodejs في Ubuntu متأخرة كثيراً عن الإصدار الأصلي، وdiscord.js v14 يحتاج بيئة تشغيل حديثة، لذا استخدم NodeSource (أعلاه) أو nvm للحصول على LTS حديث. مع nvm، شغّل which node واستخدم ذلك المسار المطلق في ملف الخدمة.

أبقِ التوكن خارج الكود: ملف .env

توكن البوت كلمة مرور تمنح تحكماً كاملاً به: لا تلصقه أبداً في bot.py أو index.js، ولا ترفعه إلى المستودع. ضعه في /opt/mybot/.env بحيث يقرأه حساب البوت وحده، واستخدم محرراً بدل echo، لأن أي توكن يُكتب في سطر الأوامر ينتهي في سجل الأوامر لديك:

sudo -u bot nano /opt/mybot/.env        # one line: DISCORD_TOKEN=your-token-here
sudo chmod 600 /opt/mybot/.env
echo ".env" | sudo -u bot tee -a /opt/mybot/.gitignore

الصيغة هي KEY=value واحد في كل سطر، بلا علامات اقتباس وبلا export. يقرؤه python-dotenv وحزمة dotenv في npm، ويستطيع systemd حقن الملف نفسه عبر EnvironmentFile= (القسم التالي)؛ والجمع بينهما غير ضار، لأن أياً من المكتبتين لا يتجاوز متغيراً موجوداً أصلاً. وإذا تسرّب التوكن يوماً، أعد تعيينه فوراً في Developer Portal ضمن Bot → Reset Token.

بوت بسيط في discord.py وdiscord.js

يقرأ المثالان التوكن من البيئة، ويفعّلان صلاحية Message Content، ويردّان على !ping. في Developer Portal، أنشئ تطبيقاً، وأضف مستخدم بوت، وانسخ التوكن (يُعرض مرة واحدة)، وفعّل Message Content Intent ضمن Bot → Privileged Gateway Intents، ثم ادعُ البوت إلى خادم تجريبي عبر مولّد روابط OAuth2 مع نطاق bot.

discord.py: /opt/mybot/bot.py

import os
import discord
from dotenv import load_dotenv

load_dotenv()

intents = discord.Intents.default()
intents.message_content = True
client = discord.Client(intents=intents)

@client.event
async def on_ready():
    print(f"Logged in as {client.user}")

@client.event
async def on_message(message):
    if message.author == client.user:
        return
    if message.content == "!ping":
        await message.channel.send("pong")

client.run(os.environ["DISCORD_TOKEN"])

discord.js: /opt/mybot/index.js

require("dotenv").config();
const { Client, GatewayIntentBits, Events } = require("discord.js");

const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.MessageContent,
  ],
});

client.once(Events.ClientReady, (c) => {
  console.log(`Logged in as ${c.user.tag}`);
});

client.on(Events.MessageCreate, (message) => {
  if (message.author.bot) return;
  if (message.content === "!ping") message.reply("pong");
});

client.login(process.env.DISCORD_TOKEN);

شغّله في المقدمة مرة واحدة: sudo -u bot /opt/mybot/.venv/bin/python /opt/mybot/bot.py أو sudo -u bot node /opt/mybot/index.js، وانتظر ظهور Logged in as، وأرسل !ping، ثم اضغط Ctrl-C. في هذه اللحظة يعيش البوت بقدر ما تعيش جلسة SSH فقط: إغلاق الطرفية يرسل SIGHUP إلى العمليات الفرعية فيموت البوت.

شغّله عبر systemd مع Restart=always

systemd هو أصلاً نظام التشغيل الأولي في Ubuntu، لذا فإن أنظف طريقة لإبقاء البوت متصلاً بعد الخروج والعطل وإعادة التشغيل هي وحدة خدمة: بلا خدمة إضافية، ومع سجلات تصل إلى journal.

الخطوة 1: اكتب الوحدة

sudo nano /etc/systemd/system/mybot.service
[Unit]
Description=Discord bot
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=bot
Group=bot
WorkingDirectory=/opt/mybot
EnvironmentFile=/opt/mybot/.env
Environment=PYTHONUNBUFFERED=1
ExecStart=/opt/mybot/.venv/bin/python /opt/mybot/bot.py
Restart=always
RestartSec=5
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/mybot

[Install]
WantedBy=multi-user.target

لـ discord.js، اضبط ExecStart=/usr/bin/node /opt/mybot/index.js واحذف سطر PYTHONUNBUFFERED. أما التوجيهات المهمة فهي:

  • Restart=always يعيد تشغيل العملية عند أي خروج، سواء كان عطلاً أو sys.exit() نظيفاً؛ وRestartSec=5 يمنع بوتاً يموت فوراً (توكن خاطئ، خطأ نحوي) من الدوران في حلقة سريعة.
  • Wants=/After=network-online.target يؤخران البدء حتى تعمل الشبكة، فلا يفشل أول تسجيل دخول بعد إعادة التشغيل بسبب DNS.
  • PYTHONUNBUFFERED=1: بدون طرفية يخزّن Python مخرجات stdout على شكل كتل، فتصل أسطر print() إلى journal متأخرة بدقائق أو عند الخروج فقط.
  • أسطر Protect* وPrivateTmp وNoNewPrivileges تجعل بقية نظام الملفات للقراءة فقط أو غير مرئية للبوت؛ أضف أي مجلد يحتاج الكتابة فيه إلى ReadWritePaths=.

الخطوة 2: التفعيل والتشغيل والتحقق

sudo systemctl daemon-reload
sudo systemctl enable --now mybot
systemctl status mybot
sudo systemctl kill --signal=KILL mybot   # simulate a crash; status is active again after 5 s

enable ينشئ الرابط الرمزي الخاص بالإقلاع و--now يبدأ الوحدة. وسطر kill هو الاختبار الحقيقي: إذا أظهر systemctl status mybot حالة active (running) بعد ثوانٍ قليلة، فسياسة إعادة التشغيل تعمل، وsudo reboot يثبت صحة مسار الإقلاع. ولرؤيتها إلى جانب بقية الخدمات، اعرض الخدمات العاملة عبر systemctl؛ ستظهر باسم mybot.service، ويؤكد systemctl is-enabled mybot أنها ستعود بعد إعادة التشغيل.

البديل: pm2، ومقارنته بـ screen وnohup وDocker

كل طريقة لإبقاء البوت حياً تجيب عن ثلاثة أسئلة: هل تنجو من الخروج من SSH، وهل تعيد التشغيل عند العطل، وهل تبدأ عند الإقلاع؟

الطريقةتنجو من الخروج من SSHتعيد التشغيل عند العطلتبدأ عند الإقلاعالخلاصة
nohup / &نعملالاللاختبارات السريعة فقط.
screen / tmuxنعملالا، إلا عبر سكربتلتصحيح الأخطاء، لا للإنتاج.
pm2نعمنعمنعم، بعد pm2 startup + pm2 saveمناسبة لفرق Node.js؛ واجهة أوامر واحدة للسجلات وإعادة التشغيل.
وحدة systemdنعمنعم (Restart=)نعم (enable)الخيار المُوصى به؛ بلا برامج إضافية، مع تقوية أمنية مدمجة.
Docker، restart: unless-stoppedنعمنعمنعم، مع خدمة Dockerمناسب حين يُشحن البوت أصلاً كصورة.

pm2 هو الخيار الشائع في عالم Node.js ويتعامل مع Python أيضاً. شغّله بالحساب الذي يملك البوت:

sudo npm install -g pm2
cd /opt/mybot
pm2 start index.js --name mybot
pm2 start bot.py --name mybot --interpreter /opt/mybot/.venv/bin/python   # Python variant
pm2 save
pm2 startup                    # prints a sudo command to run once
pm2 logs mybot
pm2 install pm2-logrotate      # ~/.pm2/logs/ otherwise grows forever

ينشئ pm2 startup وحدة systemd باسم pm2-<user> تُحيي قائمة العمليات المحفوظة عند الإقلاع، أي أن pm2 يجلس فوق systemd بدل أن يحل محله: وهذه هي الحجة الصادقة لاستخدام systemd مباشرة مع بوت واحد. أما pm2 فيستحق مكانه مع عدة عمليات Node أو فريق يعرفه مسبقاً.

إذا كنت تفضّل الحاويات، فالمكافئ هو restart: unless-stopped في ملف Compose؛ ويغطي دليل تثبيت Docker على خادم Ubuntu VPS المحرك وCompose وسلوك الإقلاع. أما تحفّظه بشأن ufw فلا يؤثر على بوت لا ينشر أي منافذ.

السجلات والتحديثات وحجم الذاكرة

السجلات

journalctl -u mybot -f                    # follow live
journalctl -u mybot --since "1 hour ago"
journalctl -u mybot -p err -b             # errors since boot
sudo journalctl --vacuum-size=200M        # cap journal size

يتولى journald التدوير والضغط تلقائياً. وإذا كان البوت يكتب ملف سجل خاصاً به، استخدم logging.handlers.RotatingFileHandler في Python أو ناقلاً دوّاراً مع pino أو winston في Node، حتى لا يملأ معالج ثرثار القرص.

التحديثات

cd /opt/mybot
sudo -u bot git pull
sudo -u bot .venv/bin/pip install -U -r requirements.txt   # Node: sudo -u bot npm ci
sudo systemctl restart mybot

إعادة التشغيل تقطع اتصال البوابة لبضع ثوانٍ؛ فتعيد المكتبة الاتصال ونادراً ما يلاحظ المستخدمون ذلك. ثبّت إصدارات المكتبات في requirements.txt أو package-lock.json واقرأ سجل التغييرات قبل أي ترقية كبرى. وأبقِ نظام التشغيل محدثاً عبر sudo apt update && sudo apt upgrade أو unattended-upgrades.

كم يحتاج البوت من الذاكرة؟

لا تحدد الحجم بأرقام عامة؛ بل قِس. يطبع systemctl status mybot سطر Memory: ويعرض pm2 list الشيء نفسه. بوت discord.py يقتصر على الأوامر يستهلك عادة عشرات الميغابايتات في وضع الخمول؛ أما بوت discord.js فيحمل بيئة تشغيل Node فوق ذلك. وتنمو الذاكرة مع الحالة: ذاكرة الأعضاء والرسائل المؤقتة في الخوادم الكبيرة، والصوت والموسيقى (عملية ffmpeg لكل بث)، وتوليد الصور أو قاعدة بيانات. عملياً، 1 غيغابايت من الذاكرة تشغّل نظام التشغيل وبوتاً صغيراً أو متوسطاً براحة؛ أما البوتات كثيفة الصوت أو تشغيل عدة بوتات على جهاز واحد فتبرر 2 غيغابايت أو أكثر، وفوق 2500 خادم يفرض ديسكورد التجزئة (sharding) التي تضاعف الاستهلاك. وهناك شبكتا أمان رخيصتان: MemoryMax=512M في الوحدة، حتى يعيد تسرّب الذاكرة تشغيل البوت بدل إسقاط الجهاز، وملف swap صغير.

كل هذا يفترض جهاز Linux بصلاحيات root يعمل على مدار الساعة. وإذا كنت لا تزال تحتاج ذلك الجهاز، فإن خادم VPS لبوتات ديسكورد من rdp.monster يصبح متصلاً بعد نحو 10 ثوانٍ من تأكيد الدفع، مع معالج وذاكرة مخصصين، وصلاحيات root كاملة، ونطاق ترددي غير محدود (ضمن الاستخدام العادل)، دون KYC، مع قبول العملات المشفرة، ابتداءً من 8.99 دولار شهرياً، بحيث تكون خطوة systemctl enable --now mybot أعلاه آخر ما تكتبه قبل أن يظهر البوت باللون الأخضر.

الأسئلة الشائعة

هل يمكنني استضافة بوت ديسكورد مجاناً على مدار الساعة؟

لم يعد ذلك موثوقاً: الخطط المجانية التي كانت تُبقي البوتات مستيقظة أُلغيت أو صارت تنام عند الخمول.
ألغت Heroku خطط dynos المجانية في نوفمبر 2022، ونقلت Replit ميزة always-on إلى عمليات النشر المدفوعة، وأنهت Glitch استضافة التطبيقات في 2025. أما الخطط المجانية المتبقية فتنام بعد الخمول، ما يغلق اتصال البوت بالبوابة. وتشغيله على حاسوبك الشخصي ينجح حتى يُعاد تشغيل الجهاز أو ينام. والخيار الموثوق الأرخص هو خادم VPS صغير بذاكرة نحو 1 غيغابايت، حيث يعيد systemd تشغيل البوت عند العطل وعند الإقلاع ولا يوقفه أحد بسبب الخمول.

هل يحتاج بوت ديسكورد إلى IP ثابت أو منافذ مفتوحة على الخادم؟

لا: يتصل البوت خارجياً بديسكورد، فلا حاجة إلى فتح أي منفذ وارد ولا أهمية لعنوان IP.
يفتح بوت البوابة اتصال WebSocket صادراً إلى ديسكورد ويستقبل الأحداث عبر الاتصال نفسه، لذا يمكن أن يبقى جدار الخادم الناري مغلقاً أمام كل شيء عدا SSH، ولا يظهر عنوان IP للخادم للمستخدمين أبداً. ولا تحتاج منفذاً مفتوحاً واسم مضيف عام إلا إذا انتقلت إلى نقاط تفاعل HTTP التي يستدعيها ديسكورد عبر رابط تسجّله، أو إذا أضفت لوحة تحكم ويب. وفي تلك الحالة ضعها خلف HTTPS عبر وكيل عكسي.

هل يمكنني تشغيل عدة بوتات ديسكورد على خادم VPS واحد؟

نعم، وحدة systemd (أو عملية pm2) واحدة لكل بوت، ويفضّل أن يكون لكل منها مستخدمها ومجلدها.
لا شيء يحصرك ببوت واحد لكل جهاز. امنح كل بوت مجلده الخاص مثل /opt/bot-a و/opt/bot-b، وملف .env خاصاً بتوكنه، وملف وحدة خاصاً به، ثم نفّذ systemctl enable --now لكل واحد. ويمنع فصل مستخدمي النظام خللاً في بوت من قراءة توكن الآخر. والميزانية المشتركة الوحيدة هي الذاكرة والمعالج: راقب systemctl status لكل وحدة، وانتقل إلى خطة أكبر حين يقترب المجموع من الحد.

هل أستضيف بوت ديسكورد على خادم Windows أم Linux؟

Linux هو الخيار الافتراضي للبوتات: أرخص وأخف، والأدوات (systemd، pm2، Docker) مصممة له.
يعمل كل من discord.py وdiscord.js على Windows، ويكون خادم Windows الخيار الصحيح إذا اعتمد البوت على تطبيق يعمل على Windows فقط أو كنت تفضّل واجهة سطح المكتب. أما لبوت عادي فيتفوق Linux: يستهلك النظام جزءاً يسيراً من الذاكرة، ولخادم مبسّط سطح هجوم شبه معدوم، وإبقاء العملية حية يتطلب وحدة systemd من عشرة أسطر. وعلى Windows ستستخدم Task Scheduler أو NSSM للحصول على السلوك نفسه عند الإقلاع مع نقرات أكثر.

Adrien Roche, محرر البنية التحتية والاستضافة

مهندس أنظمة بخبرة تزيد عن 10 سنوات في تشغيل أساطيل Windows Server وLinux. يدير أدريان وثائق البنية التحتية في rdp.monster ويكتب أدلتنا حول RDP واستضافة VPS وإدارة الخوادم والشبكات وأدوات الخصوصية.

سجّل في برنامج الموزعين لدينا

معلوماتك

إذا كان لديك أي سؤال، تواصل معنا بالضغط هنا !
الاسم(مطلوب)
أدخل عنوان بريدك الإلكتروني، ويجب أن يكون لديك حساب على manager.rdp.monster !

شركتك

أدخل عنوان موقعك الإلكتروني إن كان لديك موقع
اشرح بإيجاز كيف ستبيع خدماتنا لعملائك، مثلًا عبر الحديث مع الناس في المنتديات.

حتى الوحوش تحبّ الكوكيز!

نستخدم ملفات تعريف الارتباط لتحسين تصفّحك، ولعرض إعلانات أو محتوى مخصّص لك، ولتحليل حركة الزيارات على موقعنا. بالنقر على «قبول»، توافق على استخدامنا لملفات تعريف الارتباط.