ntfy सर्व्हर स्वतःच्या VPS वर कसा सेट करावा?
Docker Compose वापरून स्वतःच्या VPS वर ntfy कसे चालवावे ते शिका. TLS सुरक्षा, ACLs आणि वापरकर्ता प्रमाणीकरण सेट करून cron व systemd द्वारे पुश नोटिफिकेशन्स मिळवण्याची पूर्ण पद्धत.
self-hosted ntfy सर्व्हर काय करतो
एक self-hosted ntfy सर्व्हर HTTP POST विनंतीचे रूपांतर तुमच्या फोनवरील पुश नोटिफिकेशनमध्ये करतो. तुम्ही curl वापरून मेसेज पब्लिश करता आणि तो मेसेज Android ॲप, iOS ॲप, ब्राउझर टॅब किंवा HTTP कनेक्शन उघडे ठेवू शकणाऱ्या कोणत्याही उपकरणावर पोहोचतो. यासाठी कोणतीही क्लायंट लायब्ररी इन्स्टॉल करण्याची किंवा मेसेज ब्रोकर चालवण्याची गरज नसते.
ntfy मेसेजना topic द्वारे संबोधित करतो. topic म्हणजे URL पाथ मधील एक नाव, जसे की https://ntfy.example.com/alerts, आणि ज्या क्षणी कोणीतरी त्यावर मेसेज पब्लिश करतो, त्या क्षणी ते अस्तित्वात येते. डीफॉल्ट इन्स्टॉलेशनमध्ये, ज्याला त्या नावाचे ज्ञान आहे तो कोणीही तो टॉपिक वाचू शकतो आणि त्यावर लिहू शकतो, म्हणूनच प्रकल्पाच्या स्वतःच्या दस्तऐवजीकरणामध्ये टॉपिकच्या नावाची तुलना पासवर्डशी केली आहे. हे मॉडेल सार्वजनिक ntfy.sh सेवेसाठी योग्य आहे. परंतु, तुमच्या बॅकअप अपयशांची माहिती वाहून नेणाऱ्या सर्व्हरसाठी हे सुरक्षित नाही, म्हणून हे मार्गदर्शक पहिला मेसेज पाठवण्यापूर्वीच ऑथेंटिकेशन (authentication) सुरू करण्याची प्रक्रिया सांगते.
सुरुवात करण्यापूर्वी आवश्यक गोष्टी
तुमच्याकडे Ubuntu 24.04 किंवा Debian 13 वर चालणारा VPS असणे आवश्यक आहे, ज्यावर Docker Engine आणि Compose प्लगइन इन्स्टॉल केलेले असावे. तसेच, एक डोमेन नेम आणि कमी RAM असणे गरजेचे आहे. सर्व्हरच्या पब्लिक IP ॲड्रेसवर पॉइंट करणारे एक DNS (domain name system) A रेकॉर्ड तयार करा आणि ntfy.example.com वापरा. इतर कोणतीही कृती करण्यापूर्वी ते रेकॉर्ड योग्यरित्या रिझॉल्व्ह होत असल्याची खात्री करा.
dig +short ntfy.example.com
sudo ufw allow 80,443/tcp
sudo ufw statusdig ने तुमच्या सर्व्हरचा IP दर्शवला पाहिजे. जर काहीही प्रिंट झाले नाही, तर सर्टिफिकेट जारी करण्याची प्रक्रिया अपयशी ठरेल, कारण सर्टिफिकेट ऑथॉरिटी बाहेरून त्या नावाच्या अस्तित्वाची पडताळणी करते. पोर्ट 80 उघडे ठेवा, कारण Let's Encrypt च्या मागे असलेले ACME (automatic certificate management environment) हे प्रोटोकॉल HTTP चॅलेंजसाठी याचा वापर करते. ntfy कंटेनरला स्वतःला कधीही पब्लिक पोर्टची आवश्यकता नसते.
ntfy कॉन्फिगरेशन फाईल लिहा
Docker इमेजमध्ये कॉन्फिगरेशन फाईल नसते, त्यामुळे तुम्हाला ती तयार करावी लागेल. या मार्गदर्शिकेतील पुढील प्रत्येक कमांड याच फाईलमधून माहिती वाचते. सर्वप्रथम कंटेनर ज्या user ID आणि group ID ने चालणार आहे, ते शोधा.
id -u
id -g
sudo install -d -o "$(id -u)" -g "$(id -g)" /etc/ntfy /var/cache/ntfy /var/lib/ntfy
sudo nano /etc/ntfy/server.ymlbase-url: "https://ntfy.example.com"
listen-http: ":2586"
behind-proxy: true
cache-file: "/var/cache/ntfy/cache.db"
cache-duration: "12h"
auth-file: "/var/lib/ntfy/user.db"
auth-default-access: "deny-all"
enable-login: true
enable-signup: falseयातील चार ओळी अत्यंत महत्त्वाच्या आहेत. base-url हा अचूक सार्वजनिक HTTPS पत्ता असणे आवश्यक आहे, कारण ntfy याच पत्त्यावरून अटॅचमेंट लिंक्स आणि वेब ॲपच्या स्वतःच्या विनंत्या तयार करते. चुकीच्या व्हॅल्यूमुळे वेब ॲप लोड होईल, पण कोणतीही कृती (action) यशस्वी होणार नाही. listen-http: ":2586" कंटेनरमधील सर्व इंटरफेसेसना बाइंड करते. हे वरवर पाहता असुरक्षित वाटत असले तरी ते योग्य आहे; कारण कंटेनरचे स्वतःचे नेटवर्क नेमस्पेस असते. जर आपण तिथे 127.0.0.1 ला बाइंड केले, तर तो पोर्ट होस्टवरून पोहोचण्यायोग्य राहणार नाही आणि Docker चा पब्लिश केलेला पोर्ट कधीही कनेक्ट होणार नाही. auth-default-access: "deny-all" ही संपूर्ण सुरक्षा प्रणाली आहे, कारण ती स्पष्ट परवानगीशिवाय कोणालाही वाचण्याची किंवा लिहिण्याची परवानगी देत नाही. behind-proxy: true ntfy ला क्लायंटचा पत्ता X-Forwarded-For हेडरमधून घेण्यास सांगते, जेणेकरून रेट लिमिट्समध्ये रिव्हर्स प्रॉक्सीला एकच व्यस्त क्लायंट मानण्याऐवजी प्रत्यक्ष अभ्यागतांची गणना केली जाईल.
enable-login: true वेब ॲप आणि फोन ॲप्सना पासवर्डसह साइन-इन करण्याची परवानगी देते. enable-signup हे false ठेवले जाते, कारण खाजगी सर्व्हरवर स्वतःहून खाते तयार करण्याची सुविधा (self-service account creation) अनधिकृत प्रवेशासाठी एक मार्ग ठरू शकते.
sudo chown "$(id -u):$(id -g)" /etc/ntfy/server.yml
sudo chmod 600 /etc/ntfy/server.ymlDocker Compose सह ntfy चालवणे
हे /opt/ntfy/compose.yaml मध्ये ठेवा आणि 1000:1000 च्या जागी वर दिलेले दोन अंक id -u आणि id -g वापरा.
services:
ntfy:
image: binwiederhier/ntfy:v2.27.0
container_name: ntfy
command: serve
user: "1000:1000"
environment:
- TZ=UTC
volumes:
- /etc/ntfy:/etc/ntfy
- /var/cache/ntfy:/var/cache/ntfy
- /var/lib/ntfy:/var/lib/ntfy
ports:
- "127.0.0.1:2586:2586"
restart: unless-stoppedcd /opt/ntfy
sudo docker compose up -d
sudo docker compose logs ntfy
curl -s http://127.0.0.1:2586/v1/healthएक सुस्थितीत असलेला सर्व्हर {"healthy":true} ला प्रतिसाद देतो. त्या compose फाईलमधील दोन तपशील जाणीवपूर्वक ठेवले आहेत. इमेज v2.27.0 वर पिन केली आहे, जी ऑगस्ट 2026 पर्यंतची सध्याची रिलीज आहे. ती latest वर पिन केलेली नाही, कारण latest वापरल्यास पुढील docker compose pull तुमच्या सर्व्हरची आवृत्ती बदलते आणि तुम्हाला त्याबद्दलची माहिती नंतर changelog मधून मिळते. पोर्ट 127.0.0.1:2586:2586 म्हणून पब्लिश केला आहे, त्यामुळे कंटेनर फक्त होस्टच्या loopback ॲड्रेसवरूनच उपलब्ध होतो. त्याऐवजी 2586:2586 लिहिल्यास Docker तुमच्या फायरवॉल नियमांच्या आधी स्वतःचे नियम समाविष्ट करते. याचा अर्थ असा की, जरी ufw status नुसार पोर्ट बंद असल्याचे दिसत असले, तरी तो इंटरनेटवरून प्रतिसाद देतो.
जर curl ने Connection refused प्रिंट केले, तर कंटेनरचे लॉग वाचा. /var/lib/ntfy/user.db वरील परवानगी त्रुटीचा (permission error) अर्थ असा आहे की, user: ओळ त्या डिरेक्टरीजच्या मालकाशी जुळत नाही, त्यामुळे प्रक्रिया स्वतःचा डेटाबेस तयार करू शकत नाही आणि बंद होते. VPS साठी Docker Compose ची मूलभूत मार्गदर्शिका मध्ये व्हॉल्यूम मालकी आणि रीस्टार्ट धोरणांची अधिक सविस्तर माहिती दिली आहे.
Caddy वापरून TLS लागू करा
Caddy स्वतःहून प्रमाणपत्रे मिळवते आणि नूतनीकरण करते, त्यामुळे TLS (transport layer security) कार्यान्वित करण्याचा हा सर्वात सोपा मार्ग आहे.
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg
sudo chmod o+r /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install -y caddy/etc/caddy/Caddyfile मधील मजकूर काढून त्याऐवजी खालील तीन ओळी लिहा.
ntfy.example.com {
reverse_proxy 127.0.0.1:2586
}sudo systemctl reload caddy
curl -s https://ntfy.example.com/v1/healthHTTPS द्वारे तोच {"healthy":true} वापरल्यास संपूर्ण मार्ग (path) कार्यरत होतो. Caddy कडून येणारा 502 एरर म्हणजे ntfy सेवा सुरू नाही: हे sudo ss -lntp | grep 2586 वापरून तपासा. प्रमाणपत्रातील त्रुटीचा अर्थ सहसा असा असतो की DNS रेकॉर्ड चुकीचे आहे किंवा पोर्ट 80 ब्लॉक केलेले आहे, आणि sudo journalctl -u caddy -n 50 मध्ये नेमकी कोणती त्रुटी आहे हे समजते.
जर तुम्ही आधीच nginx वापरत असाल, तर ntfy दस्तऐवजीकरणात दिलेली प्रॉक्सी सेटिंग्ज कॉपी करा: proxy_http_version 1.1, proxy_buffering off, proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for, आणि read व send टाइमआउट किमान तीन मिनिटांवर सेट करा. एक सबस्क्रायबर जोपर्यंत ऐकत (listening) असतो तोपर्यंत एक HTTP कनेक्शन उघडे ठेवतो, आणि nginx डीफॉल्टनुसार 60 सेकंदांनंतर निष्क्रिय अपस्ट्रीम कनेक्शन बंद करते. यामुळे सबस्क्रायबर वारंवार पुन्हा कनेक्ट होतात आणि त्या दरम्यान पाठवलेले संदेश गहाळ होतात.
वापरकर्ते तयार करा आणि विषय मर्यादित करा
Authentication सुरू आहे आणि अद्याप कोणालाही कशाचाही प्रवेश नाही, हेच अपेक्षित आहे. स्वतःसाठी एक admin खाते आणि स्क्रिप्ट्ससाठी एक machine खाते तयार करा. हे कमांड्स कंटेनरच्या आतून /etc/ntfy/server.yml वाचतात, म्हणूनच configuration फाईल एक volume mount म्हणून जोडलेली आहे.
sudo docker compose exec ntfy ntfy user add --role=admin admin
sudo docker compose exec ntfy ntfy user add robot
sudo docker compose exec ntfy ntfy user listप्रत्येक कमांड पासवर्डसाठी विचारते. Admin ॲक्सेस लिस्टकडे दुर्लक्ष करतो आणि प्रत्येक विषय वाचू किंवा लिहू शकतो, त्यामुळे ते खाते फक्त स्वतःसाठी आणि फोन ॲपसाठी ठेवा. robot हा एक सामान्य वापरकर्ता आहे ज्याला तुम्ही प्रवेश देईपर्यंत कोणताही ॲक्सेस नसतो.
sudo docker compose exec ntfy ntfy access robot alerts write
sudo docker compose exec ntfy ntfy access robot "alerts_*" write
sudo docker compose exec ntfy ntfy accessACL (access control list) एन्ट्री म्हणजे एक वापरकर्ता, एक विषय आणि एक परवानगी. विषय एकतर नेमका नाव असतो किंवा एक पॅटर्न असतो जिथे * कोणत्याही गोष्टीशी जुळतो, त्यामुळे alerts_* मध्ये alerts_backup आणि alerts_db दोन्ही येतात, ज्यामुळे प्रत्येक host साठी स्वतंत्र कमांड देण्याची गरज पडत नाही. write ही परवानगी म्हणजे फक्त publish करणे, त्यामुळे cron job मधून चोरलेला टोकन subscribe करून पाठवलेली माहिती वाचू शकत नाही. विशेष वापरकर्तानाव everyone हे ठरवते की unauthenticated अभ्यागत काय करू शकतात, आणि याचा वापर तुम्ही फक्त तेव्हाच कराल जेव्हा तुम्हाला एखादी गोष्ट मुद्दाम सार्वजनिक करायची असेल, जसे की ntfy access everyone status read.
स्क्रिप्ट्सनी तुमचा पासवर्ड न वापरता टोकन वापरले पाहिजे.
sudo docker compose exec ntfy ntfy token add robotही कमांड tk_ ने सुरू होणारा टोकन प्रिंट करते. टोकनला नेमका त्याच वापरकर्त्याचा ॲक्सेस मिळतो ज्याचा तो आहे, त्यामुळे हा टोकन फक्त alerts विषयांवर publish करू शकतो आणि दुसरे काहीही करू शकत नाही. ntfy token list काय अस्तित्वात आहे ते दाखवते आणि ntfy token remove वापरकर्त्याचा पासवर्ड न बदलता टोकन रद्द करते.
तुमचा पहिला संदेश पाठवा आणि लॉक काम करत असल्याची खात्री करा
दरवाजा बंद असल्याची खात्री करून सुरुवात करा.
curl -s -o /dev/null -w '%{http_code}\n' -d "hello" https://ntfy.example.com/alertsहे 403 प्रिंट करते आणि 403 हे योग्य उत्तर आहे: auth-default-access: "deny-all" निनावी (anonymous) पब्लिश करण्यास नकार देते. आता एक खरा संदेश पाठवा.
curl -H "Authorization: Bearer tk_REPLACE_WITH_YOUR_TOKEN" \
-H "Title: Nightly backup finished" \
-H "Priority: default" \
-H "Tags: white_check_mark" \
-d "42 GB copied in 11 minutes" \
https://ntfy.example.com/alertsसर्व्हर साठवलेला संदेश JSON स्वरूपात परत पाठवतो, ज्यावरून तुम्हाला समजते की संदेश स्वीकारला गेला आहे आणि तो गहाळ झालेला नाही. Title ही ठळक पहिली ओळ आहे. Priority हे 1 ते 5 पर्यंत किंवा min ते urgent पर्यंतच्या नावांनी चालते आणि फोनवर आवाज येईल की नाही हे ठरवते. जेव्हा नाव एखाद्या ज्ञात इमोजी शॉर्ट कोडशी जुळते तेव्हा Tags नोटिफिकेशनवर इमोजी बनतात आणि जुळत नसल्यास ते साध्या मजकुराच्या स्वरूपात राहतात.
टर्मिनलवरून एखादा विषय (topic) पाहण्यासाठी, तो स्ट्रीम करा:
curl -s -u admin https://ntfy.example.com/alerts/rawcurl पासवर्ड विचारते. प्रत्येक संदेश एका ओळीत येतो आणि अधूनमधून दिसणाऱ्या रिकाम्या ओळी या 'कीप-अलाईव्ह' (keepalives) असतात. ब्राउझरमध्ये https://ntfy.example.com उघडून त्याच खात्याने साइन इन केल्यास तुम्हाला त्याच स्ट्रीमची वेब ॲप आवृत्ती मिळते.
एका स्क्रिप्टमुळे सर्व्हरवर ताण येऊ नये म्हणून रेट लिमिट्स सेट करा
डीफॉल्टनुसार प्रत्येक अभ्यागताला 60 विनंत्यांची मर्यादा मिळते, जी दर 5 सेकंदाला एका विनंतीच्या दराने पुन्हा भरली जाते. खाजगी सर्व्हरसाठी ही मर्यादा पुरेशी आहे, परंतु retry loop मध्ये अडकलेली एखादी स्क्रिप्ट ही संपूर्ण मर्यादा संपवू शकते. server.yml मध्ये मर्यादा जोडा.
visitor-request-limit-burst: 30
visitor-request-limit-replenish: "10s"
visitor-message-daily-limit: 500sudo docker compose restart ntfyमर्यादेपेक्षा जास्त विनंत्या करणाऱ्या अभ्यागताला संदेश मिळण्याऐवजी HTTP 429 त्रुटी मिळते. ही मर्यादा अभ्यागताच्या IP ॲड्रेसनुसार मोजली जाते, म्हणूनच behind-proxy: true महत्त्वाचे आहे: त्याशिवाय ntfy ला फक्त Caddy चा ॲड्रेस दिसतो. अशा वेळी प्रत्येक क्लायंट एकच अभ्यागत म्हणून गणला जातो आणि एक सदोष स्क्रिप्ट तुमचा फोन आणि इतर सर्व्हर वापरत असलेला कोटा संपवून टाकते.
क्रॉन जॉब अयशस्वी झाल्याची सूचना
टोकन कमांड लाईनमध्ये ठेवू नका. ps aux सर्व्हरवरील प्रत्येक वापरकर्त्याला चालू असलेल्या प्रत्येक प्रक्रियेची पूर्ण कमांड लाईन दाखवते, त्यामुळे -H द्वारे पास केलेले टोकन जोपर्यंत curl चालू आहे तोपर्यंत कोणत्याही स्थानिक खात्याद्वारे वाचले जाऊ शकते. curl कॉन्फिगरेशन फाईल वापरल्याने हे टाळता येते.
sudo install -d -m 700 /etc/ntfy-alert
printf 'header = "Authorization: Bearer tk_REPLACE_WITH_YOUR_TOKEN"\n' | sudo tee /etc/ntfy-alert/curlrc
sudo chmod 600 /etc/ntfy-alert/curlrcआता जॉब रॅप करा. हे /usr/local/bin/backup-with-alert.sh म्हणून सेव्ह करा आणि त्याला chmod 750 करा.
#!/bin/bash
out=$(/usr/local/bin/backup.sh 2>&1)
code=$?
if [ "$code" -ne 0 ]; then
printf '%s' "$out" | tail -c 1000 | curl -K /etc/ntfy-alert/curlrc \
-H "Title: backup.sh failed with exit $code" \
-H "Priority: high" \
-H "Tags: warning" \
--data-binary @- \
https://ntfy.example.com/alerts
fi
exit "$code"17 3 * * * /usr/local/bin/backup-with-alert.sh >> /var/log/backup-alert.log 2>&1$? कमांडच्या लगेच नंतरच्या ओळीवर कॅप्चर केले जाते, कारण त्यानंतर चालवलेली कोणतीही कमांड ते ओव्हरराईट करेल. आउटपुट tail -c 1000 द्वारे पाठवले जाते कारण ntfy संदेशाच्या आकारावर मर्यादा घालते आणि नोटिफिकेशन हे लॉग व्ह्यूअर नसते. शेवटचे exit "$code" मूळ स्टेटस कायम ठेवते, जेणेकरून या जॉबवर लक्ष ठेवणारी इतर कोणतीही सिस्टिम अयशस्वी झाल्याचे पाहू शकेल. एकदा स्क्रिप्ट /bin/false कडे वळवून संपूर्ण प्रक्रियेची चाचणी घ्या.
कधीही कार्यान्वित न होणारी फेल्युअर ब्रांच ही अलर्टिंग नसण्यापेक्षाही वाईट आहे, कारण शांतता म्हणजे यश असा चुकीचा अर्थ निघू शकतो. Cron तुमच्या जॉबला जवळजवळ रिकामे वातावरण आणि तुमच्या लॉगिन शेलपेक्षा खूप लहान PATH देते, त्यामुळे हाताने चालवल्यावर काम करणारी स्क्रिप्ट curl लाईनपर्यंत पोहोचण्यापूर्वीच बंद पडू शकते. क्रॉन जॉब का चालत नाही यावरील मार्गदर्शक अशा वातावरणीय त्रुटींची माहिती देते. सर्व ठिकाणी ॲब्सोल्युट पाथ वापरा आणि पहिल्या शेड्युल्ड रननंतर गृहीत धरण्याऐवजी लॉग फाईल वाचा.
systemd युनिट अयशस्वी झाल्यावर अलर्ट मिळवणे
Cron हे नियोजित कामांसाठी वापरले जाते. दीर्घकाळ चालणाऱ्या सेवांसाठी OnFailure= ची आवश्यकता असते, जे systemd द्वारे तेव्हा चालवले जाते जेव्हा एखादे युनिट failed स्थितीत येते. एक टेम्पलेट युनिट तयार करा आणि सर्व्हरवरील प्रत्येक सेवेसाठी त्याचा पुनर्वापर करा. हे /etc/systemd/system/ntfy-unit-failed@.service म्हणून सेव्ह करा.
[Unit]
Description=Send an ntfy alert because %i failed
[Service]
Type=oneshot
ExecStart=/usr/local/bin/ntfy-unit-failed %iत्यानंतर /usr/local/bin/ntfy-unit-failed करा, मोड 750 ठेवा:
#!/bin/bash
unit="$1"
journalctl -u "$unit" -n 15 --no-pager -o cat | tail -c 1000 | curl -K /etc/ntfy-alert/curlrc \
-H "Title: $unit failed on $(hostname -s)" \
-H "Priority: urgent" \
-H "Tags: rotating_light" \
--data-binary @- \
https://ntfy.example.com/alertsयाला ड्रॉप-इन (drop-in) वापरून सेवेशी जोडा, जेणेकरून पॅकेज अपग्रेडमुळे तुमचे बदल पुसले जाणार नाहीत.
sudo systemctl edit myapp.service[Unit]
OnFailure=ntfy-unit-failed@%n.service%n हे पूर्ण युनिट नावामध्ये विस्तारित होते, त्यामुळे इन्स्टन्स ntfy-unit-failed@myapp.service बनते आणि टेम्पलेटमधील %i हे myapp.service ला स्क्रिप्टमध्ये पहिला आर्ग्युमेंट म्हणून पाठवते. यामुळेच एक टेम्पलेट प्रत्येक युनिटसाठी काम करू शकते. हे काम करत असल्याची खात्री करण्यासाठी मुद्दाम अयशस्वी होणारे युनिट /etc/systemd/system/ntfy-selftest.service म्हणून सेव्ह करून तपासा.
[Unit]
Description=Deliberately failing unit
OnFailure=ntfy-unit-failed@%n.service
[Service]
Type=oneshot
ExecStart=/bin/falsesudo systemctl daemon-reload
sudo systemctl start ntfy-selftest.serviceस्टार्ट कमांड नॉन-झिरो एक्झिट कोड देते आणि Job for ntfy-selftest.service failed because the control process exited with error code प्रिंट करते, त्यानंतर साधारण एका सेकंदात फोनवर अलर्ट मिळायला हवा. चाचणीनंतर हे टेस्ट युनिट डिलीट करा.
एका गोष्टीकडे विशेष लक्ष देणे गरजेचे आहे. OnFailure= फक्त तेव्हाच चालते जेव्हा युनिट failed स्थितीत पोहोचते. ज्या सेवेमध्ये Restart=always सेट केलेले असते, ती कदाचित या स्थितीत पोहोचणार नाही, कारण systemd तिला सतत रीस्टार्ट करत राहते. युनिट तेव्हाच अयशस्वी मानले जाते जेव्हा ते StartLimitIntervalSec कालावधीत StartLimitBurst पेक्षा जास्त वेळा रीस्टार्ट होते. ज्या सेवांबद्दल तुम्हाला अलर्ट हवा आहे, त्यांच्यासाठी या दोन व्हॅल्यू सेट करा, अन्यथा क्रॅश लूप अनेक दिवस शांतपणे चालू राहील. वरील cron पॅटर्नसाठी Timers हा अधिक चांगला पर्याय आहे, कारण टायमरच्या सर्व्हिस युनिटला OnFailure= आपोआप मिळते. VPS वर systemd सेवा आणि टायमरसाठीचे मार्गदर्शक यामध्ये याचे रूपांतर कसे करायचे, हे सविस्तर दिले आहे.
Uptime monitor ला त्याच topic शी जोडा
Uptime Kuma, हे self-hosted status monitor, ntfy नोटिफिकेशन प्रकाराला सपोर्ट करते. Settings उघडा, त्यानंतर Notifications वर जा, मग Setup Notification निवडा, Ntfy निवडा, server URL https://ntfy.example.com वर सेट करा आणि topic alerts वर सेट करा. एक priority निवडा आणि robot access token पेस्ट करा. सेव्ह करण्यापूर्वी test notification पाठवून खात्री करा, कारण चुकीच्या topic नावामुळे write grant कव्हर होत नसेल तर कोणतीही त्रुटी न दाखवता ते अपयशी ठरते.
या रचनेची एक मर्यादा आहे: जर monitor त्याच VPS वर चालत असेल, तर तो VPS बंद पडल्याचे तुम्हाला सांगू शकणार नाही आणि ntfy स्वतः बंद असल्यास तो ही बातमी पोहोचवू शकणार नाही. monitor ला दुसऱ्या मशीनवर चालवा आणि monitor साठी ईमेलसारखे दुसरे नोटिफिकेशन चॅनेल वापरा, जे ntfy वर लक्ष ठेवेल. Uptime Kuma चा Push monitor प्रकार इतर त्रुटी कव्हर करतो: तुमचा cron job यशस्वीरित्या पूर्ण झाल्यावर एका push URL ला कॉल करतो आणि जेव्हा हे कॉल येणे थांबते, तेव्हा Kuma अलर्ट देतो. failure branch फक्त तेव्हाच सक्रिय होते जेव्हा job रन होतो, त्यामुळे जो job कधी सुरूच झाला नाही, त्याबद्दल ती काहीही माहिती देऊ शकत नाही.
Self-hosted ntfy हे Android आणि iPhone वर काम करते का?
Android वर, हो, कोणत्याही अटीशिवाय. Google Play किंवा F-Droid वरून अॅप इंस्टॉल करा, Settings उघडा, डीफॉल्ट सर्व्हर https://ntfy.example.com वर सेट करा, युजर मॅनेजमेंट स्क्रीनवर तुमचे खाते जोडा आणि त्यानंतर alerts ला सबस्क्राईब करा. इन्स्टंट डिलिव्हरीसाठी एक फोरग्राउंड सर्व्हिस चालू राहते, ज्यामुळे फोन 'doze mode' मध्ये असतानाही मेसेज मिळतात. त्यासोबत दिसणारी कायमस्वरूपी नोटिफिकेशन ही Android च्या फोरग्राउंड सर्व्हिसची गरज आहे, तो कोणताही बग नाही. F-Droid बिल्डमध्ये Firebase चा कोणताही कोड नसतो, त्यामुळे प्रत्येक सबस्क्रिप्शन इन्स्टंट डिलिव्हरीचा वापर करते. ntfy हे UnifiedPush डिस्ट्रिब्युटर म्हणूनही काम करू शकते, जे Google च्या पुश सर्व्हिसला एक ओपन पर्याय आहे. त्यामुळे UnifiedPush ला सपोर्ट करणारी इतर अॅप्स देखील तुमच्या सर्व्हरद्वारे मेसेज पाठवू शकतात.
iOS वर, हे एका अशा अवलंबनासह (dependency) काम करते जे तुम्ही काढू शकत नाही. Apple बॅकग्राउंडमध्ये असलेल्या अॅपला फक्त APNs (Apple push notification service) द्वारेच जागे करते. केवळ ज्याच्याकडे अॅपचे साइनिंग क्रेडेंशियल्स आहेत, तोच मेसेज पाठवू शकतो, त्यामुळे तुमच्या सर्व्हरचा अॅपशी थेट संपर्क होऊ शकत नाही. ntfy हे एका रिलेद्वारे सोडवते: तुमचा सर्व्हर मेसेज ID असलेला एक poll_request ntfy.sh कडे पाठवतो. तेथून तो Firebase आणि APNs द्वारे फॉरवर्ड केला जातो, ज्यामुळे अॅप जागे होते आणि त्यानंतर अॅप तुमच्या सर्व्हरवरून मेसेजची बॉडी मिळवते.
upstream-base-url: "https://ntfy.sh"याचा खर्च काय आहे हे स्पष्ट असावे. मेसेजची सामग्री तुमच्या सर्व्हरवरच राहते, परंतु मेसेज आला आहे ही माहिती आणि त्याचा ID तुमच्या नियंत्रणाबाहेरील इन्फ्रास्ट्रक्चरमधून जातो. हे सेटिंग नसेल तर, iPhone वर सेल्फ-होस्टेड सर्व्हरकडून येणारी नोटिफिकेशन्स उशिरा मिळतात किंवा मिळतच नाहीत, कारण अॅपला जागे करण्यासाठी काहीही नसते. रिले काढून टाकण्याचा एकमेव मार्ग म्हणजे स्वतःचे Apple डेव्हलपर खाते आणि स्वतःच्या APNs की वापरून iOS अॅप स्वतः बिल्ड आणि शिप करणे. याचा अर्थ असा की, यासाठी वार्षिक शुल्क भरावे लागेल आणि प्रत्येक अपडेटसाठी अॅप पुन्हा बिल्ड करावे लागेल. जर रिले तुमच्या वापरासाठी स्वीकारार्ह नसेल, तर अलर्टिंगसाठी Android किंवा डेस्कटॉप वेब अॅपचा वापर करा.
बॅकअप, अपग्रेड आणि इमेज पिन करणे
दोन पाथ पुन्हा तयार करता येत नाहीत: /etc/ntfy/server.yml आणि /var/lib/ntfy/user.db. दुसऱ्या फाइलमध्ये प्रत्येक वापरकर्ता, पासवर्ड हॅश, ACL एन्ट्री आणि टोकन साठवलेले असते, त्यामुळे ती खाजगी की (private key) प्रमाणे सुरक्षित ठेवा.
sudo tar czf ntfy-backup.tgz -C / etc/ntfy var/lib/ntfy
sudo chmod 600 ntfy-backup.tgzती फाइल सर्व्हरवरून बाहेर कॉपी करा. cache.db मध्ये फक्त अलीकडील संदेश असतात, जे वरील cache-duration नुसार 12 तासांचे असतात, त्यामुळे ती गमावल्यास कोणतेही नुकसान होत नाही. अपग्रेड करणे म्हणजे compose फाइलमधील टॅग बदलणे आणि पुल (pull) करणे होय.
sudo docker compose pull
sudo docker compose up -d
curl -s https://ntfy.example.com/v1/healthप्रथम रिलीज नोट्स वाचा. SQLite डेटाबेस सुरू होतानाच माइग्रेट होतात, त्यामुळे स्कीमा बदलल्यानंतर जुन्या टॅगवर परत जाणे (rollback) सुरक्षित नसते. नवीन आवृत्ती एक दिवस व्यवस्थित चालल्यानंतरच तुम्ही घेतलेला बॅकअप काढून टाका.
Gotify आणि Apprise
Gotify हा एक लहान पर्याय आहे: यात एक बायनरी, वेब UI आणि Android ॲप आहे. यात टॉपिक वाइल्डकार्ड्स नाहीत आणि अधिकृत iOS क्लायंटही नाही, त्यामुळे ज्या ठिकाणी फक्त Android चा वापर होतो अशा खाजगी सर्व्हरसाठी हे योग्य आहे. Apprise हे सर्व्हर नसून एक Python लायब्ररी आणि कमांड लाइन टूल आहे. हे एकाच संदेशाला ntfy सह शंभरहून अधिक सेवांपर्यंत पोहोचवू शकते, त्यामुळे ज्या स्क्रिप्टला एकाच वेळी अनेक ठिकाणी संदेश पाठवायचे असतात, त्यांच्यासाठी हे उपयुक्त ठरते. ntfy हे तुम्हाला सर्व्हर, HTTP API आणि दोन्ही मोबाइल प्लॅटफॉर्मवर ॲप्स उपलब्ध करून देते, म्हणूनच भाड्याने घेतलेल्या सर्व्हरवरून अलर्ट पाठवण्यासाठी हा एक सामान्य पर्याय मानला जातो.
FAQ
माझ्या ntfy सर्व्हरवर पब्लिश करताना 403 एरर का येतो?
server.yml मध्ये auth-default-access: "deny-all" सेट केलेले असल्यास, अनामिक (anonymous) पब्लिशिंग नाकारले जाते आणि हे अपेक्षित वर्तन आहे. -u user:pass किंवा -H "Authorization: Bearer tk_..." वापरून क्रेडेंशियल्स पाठवा. जर तुम्ही आधीच टोकन पाठवत असाल आणि तरीही 403 एरर येत असेल, तर त्या टोकनशी संबंधित वापरकर्त्याकडे त्या टॉपिकसाठी कोणतीही ACL एन्ट्री नाही. पूर्ण यादी पाहण्यासाठी ntfy access कमांड चालवा. लक्षात ठेवा की write परवानगीमुळे सबस्क्राइब करता येत नाही, त्यामुळे जे खाते पब्लिशिंगसाठी योग्य आहे, त्याला त्याच टॉपिकवरून डेटा वाचताना नाकारले जाऊ शकते.
स्वतःच्या ntfy सर्व्हरवर iPhone वर नोटिफिकेशन्स मिळतात का?
हो, पण यासाठी एका रिलेची गरज असते जी टाळता येत नाही. Apple फक्त APNs (Apple push notification service) द्वारेच ॲप्सना वेक-अप करते आणि फक्त ॲपचा पब्लिशरच तिथे मेसेज पाठवू शकतो. त्यामुळे ntfy मेसेज आयडी असलेला एक poll_request ntfy.sh कडे फॉरवर्ड करतो, जो तो डिव्हाइसवर रिले करतो. server.yml मध्ये upstream-base-url: "https://ntfy.sh" सेट करा आणि कंटेनर रीस्टार्ट करा. मेसेजची मुख्य माहिती (body) तुमच्या सर्व्हरवरूनच घेतली जाते. हे सेटिंग न केल्यास, iOS नोटिफिकेशन्सना विलंब होतो किंवा त्या कधीच येत नाहीत.
माझ्या cron जॉबची ntfy अलर्ट का आली नाही?
टोकन आणि टॉपिक बरोबर आहेत याची खात्री करण्यासाठी आधी ती curl कमांड स्वतंत्रपणे चालवून पहा. जर ती मॅन्युअली चालत असेल पण cron मधून चालत नसेल, तर बिघाड अलर्टच्या आधीच्या प्रक्रियेत आहे: cron जॉब्स कमीत कमी एन्वायरमेंट आणि कमी PATH सह चालवले जातात, त्यामुळे एखादी स्क्रिप्ट जी कमांडचे पूर्ण नाव वापरत नाही, ती curl लाइनपर्यंत पोहोचण्याआधीच बंद पडू शकते. पूर्ण पाथ (absolute paths) वापरा, जॉबचे आउटपुट एका लॉग फाइलमध्ये रिडायरेक्ट करा आणि पुढच्या रननंतर ती फाइल तपासा. डिलिव्हरीऐवजी 429 रिस्पॉन्स मिळणे म्हणजे रेट लिमिट काम करत आहे आणि तुमची स्क्रिप्ट खूप वेगाने पुन्हा प्रयत्न करत आहे.
मी ntfy ला सार्वजनिक इंटरनेटवर उघड (expose) करावे का?
फोन ॲप्सना मोबाइल नेटवर्कवरून सर्व्हरपर्यंत पोहोचणे आवश्यक असते, त्यामुळे auth-default-access: "deny-all" आणि टॉपिक-निहाय ACL सह सार्वजनिक HTTPS एंडपॉइंट असणे ही सामान्य रचना आहे. जोपर्यंत कोणताही टॉपिक everyone द्वारे वाचता येत नाही, तोपर्यंत हे सुरक्षित आहे. जर सर्व सबस्क्राइबर्स तुम्ही नियंत्रित करत असलेली यंत्रे असतील, तर फक्त VPN वर आधारित इन्स्टन्स वापरणे योग्य आहे. फोनसाठी हे सोयीचे नाही, कारण ॲप फक्त टनेल चालू असतानाच डेटा प्राप्त करते, त्यामुळे फोन पुन्हा कनेक्ट होईपर्यंत अलर्ट्स रांगेत (queue) राहतात.