دليل النشر

استضافة ntfy على VPS: إشعارات فورية من سكريبتاتك وCI/CD

انشر على VPS Cloud ←

دليل عملي

الأمان والمراقبة

استضافة ntfy على VPS: إشعارات فورية من سكريبتاتك وCI/CD

‏Slack يُكلف بالمقعد. رسائل البريد الإلكتروني تضيع في الضوضاء. ‏ntfy (Apache 2.0، ~32 ألف ⭐، v2.30.0 — أكتوبر 2026) يحل المشكلة بطريقة مختلفة: خادم ‏pub/sub HTTP خفيف الوزن تستضيفه ذاتيًا على ‏VPS، ويرسل إليه أي سكريبت تنبيهًا بـ ‏`curl -d`. يتلقى التطبيق المحمول الإشعار فورًا. حاوية ‏Docker واحدة، أقل من 30 ميغابايت ‏RAM، لا حساب خارجي مطلوب. في هذا المقال: النشر، المصادقة، الإعداد متعدد المستأجرين مع ‏`server.yml`، تكاملات ‏Backrest و‏Uptime Kuma وسكريبتات ‏cron، إشعارات ‏SMTP، والأخطاء الخمسة الحقيقية التي يواجهها كل مدير في الإنتاج.

16 دقيقةً للقراءةعدد الخطوات: 8
المحتويات· المشكلة: أدوات مراقبة كثيرة وقنوات إشعارات متفرقة1/14
  1. 01المشكلة: أدوات مراقبة كثيرة وقنوات إشعارات متفرقة
  2. 02ما يمنحك إياه ntfy مباشرةً
  3. 03البنية: pub/sub HTTP في حاوية واحدة
  4. 04نشر ntfy في الإنتاج: 8 خطوات
  5. 05المصادقة وتوكنات الوصول: لا تعرّض موضوعًا عامًا أبدًا
  6. 06الإعداد متعدد المستأجرين: خادم واحد، فرق متعددة
  7. 07نصيحة: أسماء المواضيع كفضاءات أسماء واستراتيجية الكتم الليلي
  8. 08استكشاف الأخطاء: 5 أخطاء حقيقية في الإنتاج
  9. 09iOS: لماذا يمر ntfy المستضاف ذاتيًا عبر ‎ntfy.sh لإرسال الـ push
  10. 10قائمة تحقق iOS: سبعة فحوص قبل التعمق أكثر
  11. 11عندما لا يصل شيء رغم كل ذلك: ما تقوله القضيتان #1305 و#1844 فعلًا
  12. 12نصيحة: لا تعتمد في تنبيه حرج على push الخاص بـ iOS وحده
  13. 13تكاملات متقدمة: Backrest وUptime Kuma وGrafana
  14. 14نصيحة: اختبر سلسلة التسليم بالكامل قبل الاعتماد عليها

المشكلة: أدوات مراقبة كثيرة وقنوات إشعارات متفرقة

‏Uptime Kuma يراقب خدماتك، ‏Beszel يراقب مقاييس ‏VPS، ‏Backrest يدير نسخك الاحتياطية، ومهام ‏cron تصمت ليلًا — إلا حين تفشل. لكل أداة قناة إشعارات خاصة: ‏Slack، بريد إلكتروني، ‏webhook، ‏Telegram. النتيجة: خمس تكاملات مختلفة للصيانة وعدم وجود رؤية موحدة حين يتعطل شيء الساعة 3 صباحًا. يحل ‏ntfy هذه المشكلة بطريقة معكوسة: أنت تستضيف مركز الإشعارات، وكل أداة أو سكريبت يرسل تنبيهاته إليه عبر ‏HTTP بسيط.

ما يمنحك إياه ntfy مباشرةً

  • أرسل إشعارًا بأمر curl بسيط — curl -d "فشل البناء" https://ntfy.example.com/تنبيهات-ci — بدون SDK أو مكتبة.
  • استقبل الإشعارات على Android وiOS والمتصفح وواجهة ntfy الويب — جميعها تشترك في نفس الموضوع.
  • إجراءات الإشعارات — أزرار تُطلق استدعاءات HTTP أو تفتح URLs أو تُشغّل أوامر على الجهاز.
  • إشعارات مجدولة — تسليم مؤجل (X-Delay: 30min) لجدولة التذكيرات من السكريبتات.
  • مستويات الأولوية (دنيا / منخفضة / افتراضية / عالية / عاجلة) مع تجاوز وضع عدم الإزعاج.
  • مرفقات — صور أو ملفات حتى 15 ميغابايت عبر رأس X-Attach.
  • إشعارات SMTP — يرسل ntfy بريدًا احتياطيًا إذا كان جهازك المحمول غير متصل أو التطبيق غير مثبت.
  • التحكم في الوصول — مستخدمون وكلمات مرور مشفرة وتوكنات وصول وقوائم تحكم بالوصول لكل موضوع.
  • أقل من 30 ميغابايت RAM وSQLite وحاوية واحدة — أخف خادم إشعارات push مستضاف ذاتيًا.

البنية: pub/sub HTTP في حاوية واحدة

‏ntfy هو ثنائي ‏Go يعمل في حاوية ‏Docker واحدة. يكشف واجهة ‏HTTP بسيطة: ‏PUT أو ‏POST على ‏/موضوعك ينشر رسالة؛ أي عميل يستمع لهذا الموضوع يتلقاها فورًا. تُخزَّن الرسائل في ‏SQLite مع استبقاء قابل للتكوين (12 ساعة افتراضيًا). في الإنتاج، يُوضع ‏ntfy خلف ‏nginx مع ‏TLS، ويُعلَّم ‏behind-proxy: true في ‏server.yml لقراءة عنوان ‏IP الحقيقي. كل الإعداد المتقدم — مصادقة، ‏SMTP، تحكم بالوصول — يعيش في ملف واحد ‏/etc/ntfy/server.yml.

نشر ntfy في الإنتاج: 8 خطوات

  1. انشر ntfy من متجر ServOrbit

    افتح لوحة ServOrbit → السوق → المراقبة → ntfy → نشر. يسحب Docker صورة binwiederhier/ntfy:v2.30.0 ويبدأ ntfy على المنفذ 8080، وتكون واجهة الويب متاحة في أقل من 5 ثوانٍ مع شهادة Let's Encrypt.

  2. أرسل أول إشعار

    من أي طرفية بها curl:
    curl -d "مرحبًا من VPS الخاص بي" https://ntfy.example.com/موضوعي
    افتح واجهة ntfy الويب، انتقل إلى الموضوع وسترى رسالتك مباشرة.

  3. أنشئ ملف server.yml الكامل

    ثبّت ملف الإعداد في الحاوية:
    base-url: https://ntfy.example.com
    listen-http: ":8080"
    behind-proxy: true
    cache-file: /var/lib/ntfy/cache.db
    cache-duration: 12h
    auth-file: /var/lib/ntfy/user.db
    auth-default-access: deny-all
    smtp-sender-addr: smtp.example.com:587
    smtp-sender-user: [email protected]
    smtp-sender-pass: motdepasseSMTP
    smtp-sender-from: [email protected]
    أعد تشغيل الحاوية بعد أي تعديل: docker restart ntfy.
    لتصل الإشعارات على iOS أيضًا، أضف ‎‎upstream-base-url: "https://ntfy.sh" إلى هذا الملف: يشرح قسم «iOS» أدناه السبب.

  4. أنشئ مستخدمين وتوكنات وصول

    # أنشئ مستخدم مدير
    docker exec -it ntfy ntfy user add --role=admin admin
    # أنشئ مستخدم للسكريبتات
    docker exec -it ntfy ntfy user add scripts
    # أنشئ توكن وصول
    docker exec -it ntfy ntfy token add scripts
    # منح حق القراءة والكتابة على موضوع محدد
    docker exec -it ntfy ntfy access scripts server-alerts rw

  5. اشترك على هاتفك مع المصادقة

    ثبّت تطبيق ntfy (Android: F-Droid أو Play Store؛ iOS: App Store). اضغط +، أدخل URL الخادم والموضوع، ثم اسم المستخدم وكلمة المرور عند الطلب. في iOS لا يصل الـ push الفوري إلا إذا كان ‎upstream-base-url معيَّنًا في خادمك (انظر القسم المخصص أدناه).

  6. أرسل تنبيهات من مهام cron باستخدام التوكن

    #!/bin/bash
    NTFY_URL="https://ntfy.example.com"
    NTFY_TOKEN="tk_AbCdEf123456"
    /usr/local/bin/backup.sh; STATUS=$?
    if [ $STATUS -eq 0 ]; then
    curl -s -H "Authorization: Bearer $NTFY_TOKEN" -H "Title: نسخ احتياطي ليلي" -H "Priority: default" -d "اكتمل في $(date)" "$NTFY_URL/cron-jobs"
    else
    curl -s -H "Authorization: Bearer $NTFY_TOKEN" -H "Title: فشل النسخ الاحتياطي" -H "Priority: urgent" -d "فشل — كود $STATUS" "$NTFY_URL/cron-jobs"
    fi

  7. اربط Backrest وUptime Kuma

    ‏Backrest: واجهة Backrest → الخطط → هوكات → أضف هوك → نوع Webhook (ntfy) → أدخل URL الموضوع والتوكن. Uptime Kuma: الإعدادات → الإشعارات → ntfy → أدخل URL الخادم والموضوع. Grafana: نقطة اتصال من نوع webhook مع رأس Authorization.

  8. فعّل إشعارات البريد الاحتياطية (SMTP)

    أضف رأس X-Email لإرسال إشعار push + بريد في آنٍ واحد:
    curl -H "Authorization: Bearer $NTFY_TOKEN" -H "Title: تنبيه حرج" -H "X-Email: [email protected]" -d "القرص ممتلئ 95%" https://ntfy.example.com/server-alerts

المصادقة وتوكنات الوصول: لا تعرّض موضوعًا عامًا أبدًا

بدون إعداد، يبدأ ‏ntfy بلا تحكم في الوصول (تذكر الوثائق أن ‎auth-default-access هو ‎read-write) — أي شخص يعرف الرابط يستطيع القراءة والكتابة. في الإنتاج: ‏auth-default-access: deny-all يغلق الخادم، ثم مستخدمون بكلمات مرور مشفرة ‏bcrypt في ‏user.db، ثم توكنات وصول مرتبطة بمستخدم محدد وقابلة للإلغاء مستقلًا. التوكن المخترق يُلغى دون تغيير كلمة المرور.

الإعداد متعدد المستأجرين: خادم واحد، فرق متعددة

ينشئ ‏ntfy مستخدمًا لكل خدمة أو فريق مع منح حق الوصول فقط لمواضيعه. المستخدم ذو دور ‏admin يرى كل شيء؛ المستخدمون العاديون محصورون بقوائم تحكم الوصول. للفرق التي تحتاج عزلًا تامًا، انشر حاويتين ‏ntfy على نطاقين فرعيين مستقلين.

نصيحة: أسماء المواضيع كفضاءات أسماء واستراتيجية الكتم الليلي

‏ci-builds لـ GitHub Actions، ‏server-alerts لـ Uptime Kuma/Beszel، ‏cron-jobs للسكريبتات، ‏backups لـ Backrest. يتيح تطبيق ntfy كتم بعض المواضيع ليلًا مع إبقاء ‏server-alerts على أعلى أولوية.

استكشاف الأخطاء: 5 أخطاء حقيقية في الإنتاج

1.‏ HTTP 403 Forbidden عند الإرسال أو الاشتراك
الرسالة: {"code":40301,"http":403,"error":"Unauthorized"}
السبب: التوكن مفقود أو منتهي الصلاحية. أعد توليد التوكن بـ ‏ntfy token add <user>.

2. إشعار مرسل لكنه لم يصل على الهاتف
على Android تحقق أولًا أن التطبيق مشترك في نسختك لا في الخادم العام ‎‎ntfy.sh (العنوان في إعدادات التطبيق). وعلى iOS فالسبب الأرجح غياب ‎‎upstream-base-url: "https://ntfy.sh" من ‎server.yml: بدون هذا الوسيط تحذّر الوثائق من أن التسليم قد يستغرق ساعات. عيّنه ثم راجع قائمة التحقق في قسم iOS أدناه. يجب تعيين ‎base-url أيضًا، لكن الوثائق تربطه بعناوين المرفقات وتذييل البريد لا بوصول الـ push.

3. روابط خاطئة في رسائل البريد الصادرة
بدون ‏base-url يُبنى تذييل البريد (رابط الإشعار) دون العنوان العام فلا ينفع من الخارج. الحل: تعيين ‏base-url وإعادة التشغيل.

4. انقطاعات WebSocket المتكررة (إعادة اتصال كل 30 ث)
السبب: مهلة ‏nginx أقل من فترة نبضات قلب ‏ntfy (‎keepalive-interval: "45s" في إعداد المثال بالوثائق). أضف ‏proxy_read_timeout 60; و‏proxy_send_timeout 60; في كتلة ‏location.

5. نفاد الذاكرة على موضوع بحجم مرور عالٍ
خفِّض ‏cache-duration إلى ‏1h ورشِّح السكريبتات لإرسال الأحداث الهامة فقط. يمكن لـ ‏ntfy استخدام ‏PostgreSQL بدل ‏SQLite لتخزينه (انظر وثائق الإعداد).

iOS: لماذا يمر ntfy المستضاف ذاتيًا عبر ‎ntfy.sh لإرسال الـ push

في iOS لا يستطيع التطبيق إبقاء اتصال مفتوح في الخلفية، وتشرح وثائق ntfy أن هذا القيد يجعل الإشعار الفوري مستحيلًا دون خادم مركزي. لذلك يرسل خادمك المستضاف ذاتيًا عن كل رسالة طلب «poll» إلى خادم upstream هو ‎‎ntfy.sh افتراضيًا، فيتولى إيقاظ التطبيق. الإعداد هو ‎‎upstream-base-url: "https://ntfy.sh". هذا الطلب لا يحمل إلا معرّف الرسالة (الترويسة ‎X-Poll-ID) وبصمة SHA-256 لعنوان الموضوع، ولا يحمل النص أبدًا: الخادم المستضاف ذاتيًا يرسل حرفيًا «New message»، ثم يجلب التطبيق المحتوى الحقيقي من خادمك. بدون ‎upstream-base-url تحذّر الوثائق من أن الإشعارات تصل في النهاية لكن التسليم قد يستغرق ساعات (من 20 إلى 30 دقيقة إذا كان الهاتف قيد الاستخدام). المعامل ‎upstream-access-token اختياري: تحصره الوثائق في حالة تجاوز حدود الخادم upstream أو كونه محميًا.

قائمة تحقق iOS: سبعة فحوص قبل التعمق أكثر

  • base-url — معيَّن على عنوان HTTPS العام لخادمك، العنوان الذي يستطيع الهاتف الوصول إليه.
  • upstream-base-url — موجود في ‎server.yml (أو كمتغير بيئة) بالقيمة ‎‎https://ntfy.sh، مع إعادة تشغيل الحاوية.
  • الخادم الافتراضي في التطبيق — في إعدادات تطبيق iOS يكون عنوان خادمك هو المعلن كخادم افتراضي.
  • الاشتراك في الخادم الصحيح — أُضيف الموضوع باختيار خادمك وليس ‎‎ntfy.sh؛ فموضوع بالاسم نفسه على الخادم العام هو موضوع آخر.
  • توكن upstream — ‎upstream-access-token لا يفيد إلا عند بلوغ حدود الخادم الوسيط؛ وما دام السبب غير مثبت فلا تضفه بدافع الانعكاس أملًا في حل المشكلة.
  • سجلات الخادم — تحقق أن الرسالة تُنشر ثم تُحوَّل إلى الخادم الوسيط. إن حدث ذلك فجانبك سليم والمشكلة بين الوسيط وApple والهاتف.
  • إعدادات الهاتف — تحديث التطبيق في الخلفية والإشعارات مفعّلان للتطبيق، ولا يوجد حاجب DNS (AdGuard Home أو Pi-hole) يصفّي ‎‎ntfy.sh.

عندما لا يصل شيء رغم كل ذلك: ما تقوله القضيتان #1305 و#1844 فعلًا

تصف هاتان القضيتان في مستودع ntfy العَرَض الذي تلاحقه: خادم مستضاف ذاتيًا، وإشعار iOS لا يظهر، ورسائل لا تظهر إلا عند تحديث التطبيق يدويًا. قُرئتا في 30 أكتوبر 2026، وكلتاهما مفتوحة ولا تحدد أي منهما سببًا مؤكدًا.

#1305 «No push notifications on ios?» (فُتحت في مارس 2025، بوسمَي ios وbug). لا يتلقى صاحب البلاغ أي إشعار، لا مع ntfy.sh ولا مع نسخته الخاصة. تقول بعض التعليقات إن إعادة تثبيت التطبيق أفادت، وتقول أخرى إن المشكلة عادت بعد أشهر. يقترح مساهم أن يعيد التطبيق الاشتراك في موضوعات Firebase عند التشغيل وقد فتح PR مسودة، مبينًا أنه لم يستطع اختبارها. ويسأل مشرف صاحبَ البلاغ هل اشتراك Firebase هو السبب، دون أن يخلص إلى نتيجة.

#1844 «No iOS Push notification, also with valid subscription» (فُتحت في يوليو 2026، بوسوم ios وserver وbug). يشغّل صاحب البلاغ ntfy في Docker مع ‎NTFY_UPSTREAM_BASE_URL على ‎https://ntfy.sh و‎NTFY_UPSTREAM_ACCESS_TOKEN معبَّأ. يقول إنه بلغ الحد المجاني وهو 250 رسالة يوميًا ثم اشترك باشتراك مدفوع. تُظهر سجلاته الرسالة منشورة ومرسلة إلى الوسيط، ومع ذلك لا يصل أي push. يجيب مساهم بأن أخطاء 429 قد تؤدي إلى حظر عنوان IP لمدة تصل إلى 4 ساعات، ويلاحظ أن اختبار ‎curl عند صاحب البلاغ ينجح (فلا حظر)، وأن الحساب أظهر 48 رسالة مرسلة من 2500. ويضيف أن إشعارات iOS متقلبة دون أن يُعرف السبب بدقة. الحل البديل المبلَّغ عنه: إيقاف «تحديث التطبيق في الخلفية» و«الإشعارات» ثم تشغيلهما من جديد في إعدادات iOS. يكتب صاحب البلاغ أنه لا يعرف لماذا ينجح ذلك؛ فقد عادت المشكلة ثم زالت دون سبب معروف، ويؤكد مستخدم آخر هذا الحل في سبتمبر 2026. ويربط بلاغ آخر حالة مشابهة بقوائم حظر DNS.

ما يمكن استنتاجه وما لا يمكن. لا حدّ يومي للرسائل ولا حظر 429 مثبتان كسبب في هذين الخيطين: فالـ429 مستبعد لعنوان IP صاحب البلاغ، وحد 250 رسالة رقم ذكره هو لا وثائق الإعداد. وتوكن upstream لا يحل المشكلة هناك. عامل القائمة أعلاه كفحوص لا كإصلاح مضمون.

نصيحة: لا تعتمد في تنبيه حرج على push الخاص بـ iOS وحده

ما دامت هاتان القضيتان مفتوحتين، ضاعف التنبيهات المهمة: أضف الترويسة ‎X-Email (انظر خطوة SMTP) لتتلقى بريدًا إلكترونيًا أيضًا، أو احتفظ بقناة ثانية على الهاتف. ويقترح المساهمون في القضيتين PWA (إشعارات الويب) بديلًا لتطبيق iOS. واختبر من الطرف إلى الطرف بعد كل تحديث للتطبيق أو لـ iOS، بنبضة watchdog الموصوفة أعلاه.

تكاملات متقدمة: Backrest وUptime Kuma وGrafana

‏Backrest يدعم ‏ntfy بشكل أصلي. ‏Uptime Kuma يدعم ‏ntfy في مدير الإشعارات. ‏Grafana يستخدم ‏webhooks عامة مع رأس ‏Authorization. جميعها تصل إلى نفس موضوع ‏ntfy وتُسلِّم الإشعارات على هاتفك فور وقوع الحدث.

نصيحة: اختبر سلسلة التسليم بالكامل قبل الاعتماد عليها

أرسل إشعارًا بـ curl، تحقق من ظهوره في واجهة الويب، وصوله على التطبيق المحمول، ووصول البريد الاحتياطي. جدول ‏cron كل 30 دقيقة يرسل نبضة حياة على موضوع ‏watchdog — إذا لم تصل النبضة، ‏ntfy نفسه توقف.

مركز إشعاراتك تحت سيطرتك

انشر ntfy على VPS من ServOrbit وأجمع كل تنبيهات المراقبة وCI/CD ومهام cron في مركز إشعارات مستضاف ذاتيًا — بلا SaaS وبلا اشتراك.