المشكلة: أدوات مراقبة كثيرة وقنوات إشعارات متفرقة
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 خطوات
انشر ntfy من متجر ServOrbit
افتح لوحة ServOrbit → السوق → المراقبة → ntfy → نشر. يسحب Docker صورة
binwiederhier/ntfy:v2.30.0ويبدأ ntfy على المنفذ 8080، وتكون واجهة الويب متاحة في أقل من 5 ثوانٍ مع شهادة Let's Encrypt.أرسل أول إشعار
من أي طرفية بها curl:
curl -d "مرحبًا من VPS الخاص بي" https://ntfy.example.com/موضوعي
افتح واجهة ntfy الويب، انتقل إلى الموضوع وسترى رسالتك مباشرة.أنشئ ملف server.yml الكامل
ثبّت ملف الإعداد في الحاوية:
base-url: https://ntfy.example.comlisten-http: ":8080"behind-proxy: truecache-file: /var/lib/ntfy/cache.dbcache-duration: 12hauth-file: /var/lib/ntfy/user.dbauth-default-access: deny-allsmtp-sender-addr: smtp.example.com:587smtp-sender-user: [email protected]smtp-sender-pass: motdepasseSMTPsmtp-sender-from: [email protected]
أعد تشغيل الحاوية بعد أي تعديل:docker restart ntfy.
لتصل الإشعارات على iOS أيضًا، أضف upstream-base-url: "https://ntfy.sh"إلى هذا الملف: يشرح قسم «iOS» أدناه السبب.أنشئ مستخدمين وتوكنات وصول
# أنشئ مستخدم مدير
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اشترك على هاتفك مع المصادقة
ثبّت تطبيق ntfy (Android: F-Droid أو Play Store؛ iOS: App Store). اضغط +، أدخل URL الخادم والموضوع، ثم اسم المستخدم وكلمة المرور عند الطلب. في iOS لا يصل الـ push الفوري إلا إذا كان
upstream-base-urlمعيَّنًا في خادمك (انظر القسم المخصص أدناه).أرسل تنبيهات من مهام cron باستخدام التوكن
#!/bin/bash
NTFY_URL="https://ntfy.example.com"NTFY_TOKEN="tk_AbCdEf123456"/usr/local/bin/backup.sh; STATUS=$?if [ $STATUS -eq 0 ]; thencurl -s -H "Authorization: Bearer $NTFY_TOKEN" -H "Title: نسخ احتياطي ليلي" -H "Priority: default" -d "اكتمل في $(date)" "$NTFY_URL/cron-jobs"elsecurl -s -H "Authorization: Bearer $NTFY_TOKEN" -H "Title: فشل النسخ الاحتياطي" -H "Priority: urgent" -d "فشل — كود $STATUS" "$NTFY_URL/cron-jobs"fiاربط Backrest وUptime Kuma
Backrest: واجهة Backrest → الخطط → هوكات → أضف هوك → نوع
Webhook (ntfy)→ أدخل URL الموضوع والتوكن. Uptime Kuma: الإعدادات → الإشعارات → ntfy → أدخل URL الخادم والموضوع. Grafana: نقطة اتصال من نوع webhook مع رأس Authorization.فعّل إشعارات البريد الاحتياطية (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 نفسه توقف.