SSD Nodes Learn 🎉 VPS $5.50/மாதம் முதல்

Self-hosted ntfy server அமைப்பது எப்படி?

Docker Compose மூலம் உங்கள் VPS-ல் ntfy server-ஐ TLS ஆதரவுடன் நிறுவுவது எப்படி என்பதை அறிக. ACL மற்றும் user authentication பயன்படுத்தி பாதுகாப்பான push alerts பெறுங்கள்.

சுயமாக இயங்கும் ntfy server-ன் செயல்பாடுகள்

சுயமாக இயங்கும் (self-hosted) ntfy server, ஒரு HTTP POST கோரிக்கையை உங்கள் கைபேசிக்கான push notification-ஆக மாற்றுகிறது. நீங்கள் curl மூலம் தகவலை அனுப்பும்போது, அது Android app, iOS app, browser tab அல்லது HTTP இணைப்பைத் திறந்த நிலையில் வைத்திருக்கக்கூடிய எந்தவொரு சாதனத்திற்கும் சென்றடையும். இதற்காக எந்தவொரு client library-யையும் நிறுவ வேண்டியதில்லை, message broker-ஐ இயக்க வேண்டிய அவசியமும் இல்லை.

ntfy தகவல்களை topic அடிப்படையில் கையாளுகிறது. Topic என்பது URL பாதையில் உள்ள ஒரு பெயர், உதாரணமாக https://ntfy.example.com/alerts. இதற்கு யாராவது தகவலை அனுப்பும் தருணத்திலேயே அந்த topic உருவாகிவிடும். இயல்பான அமைப்பில் (default install), அந்தப் பெயர் தெரிந்த எவரும் அந்த topic-ல் தகவல்களைப் படிக்கவோ அல்லது எழுதவோ முடியும். இதனால்தான், ஒரு topic பெயரை கடவுச்சொல்லுக்கு (password) இணையாகக் கருத வேண்டும் என்று இந்தத் திட்டத்தின் ஆவணங்கள் குறிப்பிடுகின்றன. பொதுவான ntfy.sh சேவைக்கு இந்த முறை பொருத்தமானது. ஆனால், உங்கள் backup தோல்விகள் போன்ற முக்கியமான தகவல்களைக் கையாளும் server-க்கு இது பாதுகாப்பானது அல்ல. எனவே, முதல் தகவலை அனுப்பும் முன்பே இந்த வழிகாட்டி மூலம் authentication-ஐ எவ்வாறு செயல்படுத்துவது என்பதைப் பார்ப்போம்.

தொடங்குவதற்கு முன் உங்களுக்குத் தேவையானவை

உங்களுக்கு Ubuntu 24.04 அல்லது Debian 13 இயங்கும் ஒரு VPS, Docker Engine மற்றும் Compose plugin, ஒரு domain name, மற்றும் மிகக்குறைந்த RAM தேவை. உங்கள் server-ன் public IP address-ஐக் குறிக்கும் வகையில் ஒரு DNS (domain name system) A record-ஐ உருவாக்கவும் ntfy.example.com. எதையும் தொடங்குவதற்கு முன், அந்த domain சரியாக resolve ஆகிறதா என்பதை உறுதிப்படுத்தவும்.

dig +short ntfy.example.com
sudo ufw allow 80,443/tcp
sudo ufw status

dig உங்கள் server-ன் IP-ஐக் காட்ட வேண்டும். இது எதையும் காட்டவில்லை என்றால், certificate வழங்குவதில் தோல்வி ஏற்படும். ஏனெனில், certificate authority அந்தப் பெயரை வெளியிலிருந்து சரிபார்க்கிறது. Let's Encrypt-ன் பின்னணியில் உள்ள ACME (automatic certificate management environment) protocol, HTTP challenge-க்காக Port 80-ஐப் பயன்படுத்துவதால், அதைத் திறந்து வைத்திருக்க வேண்டும். ntfy container-க்கு எந்தவொரு public port-ம் தேவையில்லை.

ntfy config கோப்பை உருவாக்குதல்

Docker image-ல் config கோப்பு இல்லாததால், நீங்கள் ஒன்றை உருவாக்க வேண்டும். இந்த வழிகாட்டியின் பிற்பகுதியில் உள்ள அனைத்து கட்டளைகளும் இதிலிருந்தே தகவல்களைப் படிக்கும். முதலில், container எந்த 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.yml
base-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 இதைப் பயன்படுத்தியே attachment இணைப்புகளையும், web app-ன் சொந்த கோரிக்கைகளையும் உருவாக்குகிறது. இதில் தவறான மதிப்பு இருந்தால், web app ஏற்றப்படும், ஆனால் எந்தச் செயல்பாடும் தோல்வியடையும். listen-http: ":2586" என்பது container-க்குள் உள்ள அனைத்து interfaces-களிலும் இணையும்; இது கவனக்குறைவாகத் தெரிந்தாலும், இதுவே சரியானது. ஏனெனில், container-க்கு என்று தனி network namespace உள்ளது. எனவே, அங்கு 127.0.0.1-ல் இணைந்தால், host-லிருந்து அந்த port-ஐ அணுக முடியாது, Docker-ன் published port-ம் இணைக்கப்படாது. auth-default-access: "deny-all" என்பது முழுமையான பாதுகாப்பு அம்சமாகும்; இது முறையான அனுமதி இல்லாத எவரையும் படிக்கவோ அல்லது எழுதவோ அனுமதிக்காது. behind-proxy: true என்பது client முகவரியை X-Forwarded-For header-லிருந்து எடுக்குமாறு ntfy-க்கு அறிவுறுத்துகிறது. இதனால், reverse proxy-ஐ ஒரே ஒரு பிஸியான client-ஆகக் கருதாமல், உண்மையான பார்வையாளர்களைக் கணக்கிட்டு rate limits சரியாகச் செயல்படும்.

enable-login: true, web app மற்றும் phone app-கள் கடவுச்சொல் மூலம் உள்நுழைய அனுமதிக்கிறது. enable-signup என்பது false என்றே இருக்க வேண்டும், ஏனெனில் ஒரு private server-ல் சுயமாகக் கணக்கு உருவாக்கும் வசதி என்பது தேவையற்ற பாதுகாப்புச் சிக்கல்களை உருவாக்கும்.

sudo chown "$(id -u):$(id -g)" /etc/ntfy/server.yml
sudo chmod 600 /etc/ntfy/server.yml

Docker 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-stopped
cd /opt/ntfy
sudo docker compose up -d
sudo docker compose logs ntfy
curl -s http://127.0.0.1:2586/v1/health

சரியாக இயங்கும் server {"healthy":true} என்று பதிலளிக்கும். அந்த compose file-ல் உள்ள இரண்டு விவரங்கள் வேண்டுமென்றே சேர்க்கப்பட்டுள்ளன. image-ஆனது v2.27.0-க்கு pinned செய்யப்பட்டுள்ளது (ஆகஸ்ட் 2026 நிலவரப்படி இதுவே தற்போதைய release). latest-க்கு பதிலாக இவ்வாறு செய்யப்பட்டுள்ளது, ஏனெனில் latest-ஐப் பயன்படுத்தினால், அடுத்த docker compose pull உங்கள் server version-ஐ மாற்றிவிடும், அதன் பிறகு changelog-ஐப் பார்த்தே நீங்கள் அதை அறிய முடியும். port-ஆனது 127.0.0.1:2586:2586 என வெளியிடப்பட்டுள்ளது, எனவே container-ஐ host-ன் loopback address மூலம் மட்டுமே அணுக முடியும். அதற்கு பதிலாக 2586:2586 என்று எழுதினால், Docker அதன் சொந்த firewall விதிகளை உங்களுடைய விதிகளுக்கு முன்பாகச் செருகிவிடும். இதன் பொருள், ufw status port மூடப்பட்டிருப்பதாகக் காட்டினாலும், இணையத்திலிருந்து அந்த port-க்கு பதில் கிடைக்கும் என்பதாகும்.

curl கட்டளை Connection refused என்று அச்சிட்டால், container log-ஐப் படிக்கவும். /var/lib/ntfy/user.db-ல் permission error ஏற்பட்டால், user: வரியில் உள்ள விவரங்கள் அந்த directories-ன் உரிமையாளருடன் (owner) பொருந்தவில்லை என்று அர்த்தம். இதனால் process-ஆல் அதன் சொந்த database-ஐ உருவாக்க முடியாமல் வெளியேறுகிறது. VPS-க்கான Docker Compose அடிப்படை வழிகாட்டி volume ownership மற்றும் restart policies பற்றிய கூடுதல் விவரங்களை வழங்குகிறது.

Caddy மூலம் TLS-ஐ முன்னால் அமைத்தல்

Caddy தானாகவே certificate-ஐக் கோரி புதுப்பித்துக்கொள்ளும். இது 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/health

HTTPS வழியாக அதே {"healthy":true} கிடைத்தால், முழு பாதையும் சரியாக வேலை செய்கிறது என்று அர்த்தம். Caddy-யிடமிருந்து 502 கிடைத்தால், ntfy இயங்கவில்லை என்று பொருள்: sudo ss -lntp | grep 2586 மூலம் அதைச் சரிபார்க்கவும். Certificate பிழை ஏற்பட்டால், பொதுவாக DNS பதிவு தவறாக உள்ளது அல்லது port 80 தடுக்கப்பட்டுள்ளது என்று அர்த்தம்; sudo journalctl -u caddy -n 50 எந்தப் பிழை என்பதைத் தெரிவிக்கும்.

நீங்கள் ஏற்கனவே nginx பயன்படுத்துகிறீர்கள் என்றால், ntfy ஆவணங்களில் உள்ள proxy அமைப்புகளை நகலெடுக்கவும்: proxy_http_version 1.1, proxy_buffering off, proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for, மற்றும் read/send timeouts-ஐ குறைந்தது மூன்று நிமிடங்களுக்கு அமைக்கவும். ஒரு subscriber, தான் listening நிலையில் இருக்கும் வரை ஒரு HTTP connection-ஐத் திறந்து வைத்திருக்கும். nginx இயல்பாக 60 வினாடிகளுக்குப் பிறகு idle upstream connection-ஐ மூடிவிடும் என்பதால், subscribers மீண்டும் மீண்டும் இணைப்பை ஏற்படுத்த முயற்சிப்பார்கள்; அந்த இடைவெளியில் அனுப்பப்படும் செய்திகள் தவறிவிடும்.

பயனர்களை உருவாக்குதல் மற்றும் தலைப்புகளைக் கட்டுப்படுத்துதல்

Authentication செயல்பாட்டில் உள்ளது, ஆனால் யாருக்கும் எதையும் அணுக அனுமதி இல்லை. இதுவே நோக்கம். உங்களுக்காக ஒரு admin கணக்கையும், scripts-க்காக ஒரு machine கணக்கையும் உருவாக்கவும். இந்த commands container-க்குள் இருந்து /etc/ntfy/server.yml-ஐ வாசிக்கின்றன, இதனால்தான் config file ஒரு 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, access list-ஐப் புறக்கணித்து அனைத்து தலைப்புகளையும் படிக்கவும் எழுதவும் முடியும், எனவே அந்த கணக்கை உங்களுக்கும் உங்கள் phone app-க்கும் மட்டும் வைத்துக்கொள்ளுங்கள். 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 access

ஒரு ACL (access control list) entry என்பது ஒரு பயனர், ஒரு தலைப்பு மற்றும் ஒரு அனுமதி ஆகியவற்றைக் கொண்டது. தலைப்பு என்பது ஒரு குறிப்பிட்ட பெயராகவோ அல்லது * எதையும் குறிக்கும் ஒரு pattern-ஆகவோ இருக்கலாம். எனவே alerts_* என்பது alerts_backup மற்றும் alerts_db ஆகிய இரண்டையும் உள்ளடக்கும், ஒவ்வொரு host-க்கும் தனித்தனியாக command இயக்கத் தேவையில்லை. write என்ற அனுமதி publish செய்வதற்கு மட்டுமே; எனவே cron job-லிருந்து திருடப்பட்ட ஒரு token-ஆல் subscribe செய்து அனுப்பப்பட்ட தகவலைப் படிக்க முடியாது. everyone என்ற சிறப்புப் பயனர் பெயர், authentication இல்லாத பார்வையாளர்கள் என்ன செய்யலாம் என்பதைத் தீர்மானிக்கிறது. இதை ntfy access everyone status read போன்ற பொதுவான தலைப்புகளைத் திறக்க மட்டுமே பயன்படுத்த வேண்டும்.

Scripts உங்கள் கடவுச்சொல்லைப் பயன்படுத்தாமல், ஒரு token-ஐப் பயன்படுத்த வேண்டும்.

sudo docker compose exec ntfy ntfy token add robot

இந்த command tk_-ல் தொடங்கும் ஒரு token-ஐ அச்சிடும். ஒரு token, அது எந்தப் பயனருக்குச் சொந்தமானதோ அதே அனுமதியைப் பெறும். எனவே இது alerts தலைப்புகளில் publish செய்ய மட்டுமே முடியும், வேறு எதையும் செய்ய முடியாது. ntfy token list தற்போதுள்ளவற்றைத் திரையிடும், ntfy token remove பயனரின் கடவுச்சொல்லை மாற்றாமல் ஒரு token-ஐ நீக்கும்.

உங்கள் முதல் செய்தியை அனுப்பி, பூட்டு சரியாக வேலை செய்கிறதா எனச் சரிபார்க்கவும்

முதலில் கதவு மூடப்பட்டுள்ளதா என்பதைச் சரிபார்க்கவும்.

curl -s -o /dev/null -w '%{http_code}\n' -d "hello" https://ntfy.example.com/alerts

இது 403 என்பதை வெளியிடும், மேலும் 403 என்பதே சரியான விடையாகும்: auth-default-access: "deny-all" அநாமதேய வெளியீட்டை (anonymous publish) நிராகரிக்கிறது. இப்போது உண்மையான செய்தியை அனுப்பவும்.

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

சேவையகம் (server) சேமிக்கப்பட்ட செய்தியை JSON வடிவில் பதிலளிக்கும், இது செய்தி நிராகரிக்கப்படாமல் ஏற்றுக்கொள்ளப்பட்டதை உறுதிப்படுத்துகிறது. Title என்பது தடித்த எழுத்துக்களில் உள்ள முதல் வரியாகும். Priority என்பது 1 முதல் 5 வரை அல்லது min முதல் urgent வரையிலான பெயர்களைக் கொண்டு இயங்கும், இது தொலைபேசியில் ஒலி எழுப்ப வேண்டுமா என்பதைத் தீர்மானிக்கிறது. Tags என்பது அறியப்பட்ட ஈமோஜி குறியீட்டுடன் (emoji short code) பொருந்தும்போது அறிவிப்பில் ஈமோஜியாக மாறும், பொருந்தாதபோது சாதாரண உரையாகவே இருக்கும்.

ஒரு முனையத்திலிருந்து (terminal) ஒரு தலைப்பைக் கண்காணிக்க, அதை stream செய்யவும்:

curl -s -u admin https://ntfy.example.com/alerts/raw

curl கடவுச்சொல்லைக் கேட்கும். ஒவ்வொரு செய்தியும் ஒரு வரியாக வந்து சேரும், அவ்வப்போது தோன்றும் வெற்று வரிகள் keepalives ஆகும். உலாவியில் https://ntfy.example.com-ஐத் திறந்து, அதே கணக்கைக் கொண்டு உள்நுழைந்தால், அதே stream-ன் இணையப் பதிப்பைப் (web app version) பெறலாம்.

ஒரே script server-ஐ முடக்காதவாறு rate limits அமைத்தல்

இயல்பாக, ஒவ்வொரு visitor-க்கும் 60 requests கொண்ட bucket ஒதுக்கப்படுகிறது; இது ஒவ்வொரு 5 வினாடிக்கும் ஒரு request என்ற விகிதத்தில் நிரப்பப்படும். ஒரு private server-க்கு இது தாராளமானது, ஆனால் retry loop-ல் சிக்கிய ஒரு script இதை முழுமையாகப் பயன்படுத்திவிடும். server.yml-ல் வரம்புகளைச் சேர்க்கவும்.

visitor-request-limit-burst: 30
visitor-request-limit-replenish: "10s"
visitor-message-daily-limit: 500
sudo docker compose restart ntfy

வரம்பைத் தாண்டும் visitor-க்கு, செய்தி வழங்கப்படுவதற்குப் பதிலாக HTTP 429 பிழை கிடைக்கும். இந்த வரம்பு visitor-ன் முகவரியைக் கொண்டு கணக்கிடப்படுகிறது. இதனால்தான் behind-proxy: true மிக முக்கியமானது: இது இல்லையெனில், ntfy ஆனது Caddy-ன் முகவரியை மட்டுமே பார்க்கும். அப்போது அனைத்து client-களும் ஒரே visitor-ஆகக் கருதப்படுவார்கள்; ஒரு script செய்யும் அதிகப்படியான கோரிக்கைகள், உங்கள் phone மற்றும் பிற server-கள் பகிர்ந்து கொள்ளும் bucket-ஐ காலி செய்துவிடும்.

தோல்வியடையும் cron job-லிருந்து எச்சரிக்கை பெறுதல்

கட்டளை வரியில் (command line) token-ஐ வைக்க வேண்டாம். ps aux, கணினியில் இயங்கும் ஒவ்வொரு process-ன் முழு கட்டளை வரியையும் அனைத்து பயனர்களுக்கும் காட்டும், எனவே -H மூலம் அனுப்பப்படும் token-ஐ, curl இயங்கும் வரை எந்தவொரு local account-ம் படிக்க முடியும். ஒரு curl config file-ஐப் பயன்படுத்துவது இதைத் தவிர்க்கும்.

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

இப்போது இந்த job-ஐ ஒரு wrapper-க்குள் கொண்டு வரவும். இதை /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

$?, கட்டளைக்கு அடுத்த வரியிலேயே பெறப்படுகிறது, ஏனெனில் அடுத்து இயங்கும் கட்டளை அதை அழித்துவிடும். ntfy அதிகபட்ச செய்தி அளவைக் கட்டுப்படுத்துவதால், வெளியீடு tail -c 1000 வழியாகச் செல்கிறது; notification என்பது log viewer அல்ல. இறுதியில் உள்ள exit "$code", அசல் status-ஐ அப்படியே வைத்திருக்கும், எனவே இந்த job-ஐக் கண்காணிக்கும் பிற அமைப்புகள் தோல்வியைக் கண்டறிய முடியும். இந்த script-ஐ ஒருமுறை /bin/false-க்கு அனுப்பி முழு அமைப்பையும் சோதிக்கவும்.

எச்சரிக்கை தராத ஒரு தோல்வி, எச்சரிக்கையே இல்லாததை விட மோசமானது, ஏனெனில் அமைதி என்பது வெற்றி என்று தவறாகக் கருதப்படலாம். Cron உங்கள் job-க்கு மிகக் குறைந்த environment-ஐயும், உங்கள் login shell-ஐ விட மிகச் சிறிய PATH-ஐயும் வழங்குகிறது; எனவே, நீங்கள் நேரடியாக இயக்கும்போது வேலை செய்யும் script, curl வரியை அடையும் முன்பே நின்றுவிடலாம். cron job ஏன் இயங்கவில்லை என்பதற்கான வழிகாட்டி இத்தகைய environment சிக்கல்களை விளக்குகிறது. எல்லா இடங்களிலும் absolute paths-ஐப் பயன்படுத்தவும், முதல்முறை திட்டமிட்டபடி இயங்கிய பிறகு, ஊகிக்காமல் log file-ஐப் படிக்கவும்.

systemd unit தோல்வியடையும் போது எச்சரிக்கை பெறுதல்

Cron திட்டமிடப்பட்ட பணிகளைச் செய்கிறது. நீண்ட நேரம் இயங்கும் சேவைகளுக்கு OnFailure= தேவைப்படுகிறது; ஒரு unit failed நிலையை அடையும் போது systemd இதை இயக்குகிறது. ஒரு template unit-ஐ உருவாக்கி, server-ல் உள்ள அனைத்து சேவைகளுக்கும் அதையே பயன்படுத்தலாம். இதை /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 கட்டளையைப் பயன்படுத்தி, mode 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 மூலம் ஒரு சேவையுடன் இணைக்கவும்; அப்போதுதான் package upgrade செய்யப்படும்போது உங்கள் மாற்றங்கள் அழியாது.

sudo systemctl edit myapp.service
[Unit]
OnFailure=ntfy-unit-failed@%n.service

%n என்பது முழுமையான unit பெயராக விரிவடையும், எனவே அந்த instance ntfy-unit-failed@myapp.service ஆக மாறும். template-க்குள் இருக்கும் %i, myapp.service-ஐ அந்த script-க்கு முதல் argument-ஆக வழங்கும். இதுவே ஒரு template-ஐ அனைத்து unit-களுக்கும் பயன்படுத்த உதவுகிறது. இது செயல்படுகிறதா என்பதைச் சோதிக்க, வேண்டுமென்றே தோல்வியடையும் ஒரு unit-ஐ /etc/systemd/system/ntfy-selftest.service என்ற பெயரில் சேமித்து உறுதிப்படுத்தவும்.

[Unit]
Description=Deliberately failing unit
OnFailure=ntfy-unit-failed@%n.service

[Service]
Type=oneshot
ExecStart=/bin/false
sudo systemctl daemon-reload
sudo systemctl start ntfy-selftest.service

start கட்டளை non-zero exit code-ஐத் தந்து Job for ntfy-selftest.service failed because the control process exited with error code-ஐ அச்சிடும், ஒரு நொடிக்குள் உங்கள் தொலைபேசி எச்சரிக்கை செய்யும். சோதனையின் முடிவில் அந்த test unit-ஐ நீக்கிவிடவும்.

ஒரு முக்கியமான விஷயத்தைக் கவனிக்க வேண்டும். OnFailure= ஒரு unit failed நிலையை அடையும் போது மட்டுமே இயங்கும். Restart=always கொண்ட ஒரு சேவை அந்த நிலையை அடையாமலேயே போகலாம், ஏனெனில் systemd அதைத் தொடர்ந்து restart செய்துகொண்டே இருக்கும். StartLimitIntervalSec காலத்திற்குள் StartLimitBurst எண்ணிக்கையிலான restart-களைத் தாண்டும்போது மட்டுமே அந்த unit தோல்வியடைந்ததாகக் கருதப்படும். நீங்கள் கண்காணிக்க விரும்பும் எந்தவொரு சேவைக்கும் இந்த இரண்டு மதிப்புகளை அமைக்கவும், இல்லையெனில் சேவை தொடர்ந்து crash ஆகிக்கொண்டே இருக்கும், ஆனால் உங்களுக்குத் தெரியாது. மேலே குறிப்பிட்ட cron முறைக்கு மாற்றாக Timers சிறந்தவை, ஏனெனில் ஒரு timer-ன் service unit-க்கு OnFailure= தானாகவே கிடைத்துவிடும். VPS-ல் systemd services மற்றும் timers குறித்த வழிகாட்டி இதைப் பற்றி விரிவாக விளக்குகிறது.

Uptime monitor-ஐ அதே topic-ல் இணைத்தல்

Uptime Kuma, the self-hosted status monitor, ntfy notification வகையை வழங்குகிறது. Settings பகுதிக்குச் சென்று, Notifications என்பதைத் தேர்ந்தெடுத்து, Setup Notification என்பதைக் கிளிக் செய்யவும். அதில் Ntfy-ஐத் தேர்வு செய்து, server URL-ஐ https://ntfy.example.com என்றும், topic-ஐ alerts என்றும் அமைக்கவும். ஒரு priority-ஐத் தேர்ந்தெடுத்து, robot access token-ஐ உள்ளிடவும். சேமிப்பதற்கு முன் test notification-ஐ அனுப்பிச் சரிபார்க்கவும்; ஏனெனில், தவறான topic பெயர் இருந்தால், அதை உள்ளடக்கிய write அனுமதி இல்லாதபோது எந்தப் பிழையும் காட்டப்படாமல் செயல் தோல்வியடையும்.

இந்த அமைப்பின் நடைமுறை வரம்பு இதுதான்: அதே VPS-ல் இயங்கும் monitor-ஆல் அந்த VPS செயலிழந்ததை உங்களுக்குத் தெரிவிக்க முடியாது; மேலும், ntfy செயலிழந்தால் அந்தத் தகவலை ntfy-ஆல் அனுப்ப முடியாது. எனவே, monitor-ஐ வேறொரு கணினியில் இயக்கவும். ntfy-ஐக் கண்காணிக்கும் monitor-க்கு, மின்னஞ்சல் போன்ற இரண்டாவது notification channel-ஐ வழங்கவும். Uptime Kuma-வின் Push monitor வகை மற்றொரு குறைபாட்டைச் சரிசெய்கிறது: உங்கள் cron job வெற்றிகரமாக முடிந்ததும் ஒரு push URL-ஐ அழைக்கும்; அந்த அழைப்புகள் வருவது நின்றால் Kuma எச்சரிக்கை செய்யும். ஒரு failure branch, job இயங்கும்போது மட்டுமே செயல்படும் என்பதால், தொடங்கப்படாத job-களைப் பற்றி அதனால் தெரிவிக்க முடியாது.

சுயமாக ஹோஸ்ட் செய்யப்படும் ntfy, Android மற்றும் iPhone-ல் வேலை செய்யுமா?

Android-ல், எந்த நிபந்தனையும் இன்றி இது வேலை செய்யும். Google Play அல்லது F-Droid-லிருந்து செயலியை நிறுவி, Settings-ஐத் திறந்து, default server-ஐ https://ntfy.example.com என அமைக்கவும். பயனர் மேலாண்மைத் திரையில் உங்கள் கணக்கைச் சேர்த்து, பின் alerts-க்கு subscribe செய்யவும். உடனடி டெலிவரிக்கு ஒரு foreground service இயங்கிக்கொண்டே இருக்க வேண்டும், அப்போதுதான் போன் doze mode-ல் இருந்தாலும் செய்திகள் வந்து சேரும். இதனுடன் வரும் நிரந்தர அறிவிப்பு (permanent notification) என்பது Android-ன் foreground service விதியாகும், இது பிழை அல்ல. F-Droid பதிப்பில் Firebase குறியீடு எதுவும் இல்லை, எனவே ஒவ்வொரு subscription-ம் உடனடி டெலிவரியைப் பயன்படுத்துகிறது. ntfy ஒரு UnifiedPush distributor-ஆகவும் செயல்பட முடியும். இது Google-ன் push சேவைக்கு மாற்றான திறந்தநிலை அமைப்பாகும், எனவே UnifiedPush-ஐ ஆதரிக்கும் பிற செயலிகளும் உங்கள் server வழியாக செய்திகளை அனுப்ப முடியும்.

iOS-ல், நீக்க முடியாத ஒரு சார்புநிலையுடன் (dependency) இது வேலை செய்கிறது. Apple, பின்னணியில் இயங்கும் செயலியை APNs (Apple push notification service) வழியாக மட்டுமே எழுப்புகிறது. செயலியின் signing credentials வைத்திருப்பவர் மட்டுமே அதற்கு அனுப்ப முடியும் என்பதால், உங்கள் server-ஆல் நேரடியாகச் செயலியைத் தொடர்பு கொள்ள முடியாது. ntfy இதை ஒரு relay மூலம் தீர்க்கிறது: உங்கள் server, செய்தி ID-யைக் கொண்ட ஒரு poll_request-ஐ ntfy.sh-க்கு அனுப்புகிறது. அது Firebase மற்றும் APNs வழியாகச் செயலியை எழுப்புகிறது, பின்னர் செயலி உங்கள் server-லிருந்து செய்தியின் உள்ளடக்கத்தைப் பெற்றுக்கொள்கிறது.

upstream-base-url: "https://ntfy.sh"

இதற்கான செலவு என்ன என்பதைத் தெளிவாகப் புரிந்துகொள்ளுங்கள். செய்தியின் உள்ளடக்கம் உங்கள் server-லேயே இருக்கும், ஆனால் ஒரு செய்தி வந்ததற்கான தகவல் மற்றும் அதன் ID, நீங்கள் நிர்வகிக்காத உள்கட்டமைப்பு வழியாகச் செல்லும். இந்த அமைப்பு இல்லையென்றால், iPhone-ல் சுயமாக ஹோஸ்ட் செய்யப்பட்ட server-லிருந்து வரும் அறிவிப்புகள் தாமதமாக வரும் அல்லது வராமலே போகும், ஏனெனில் செயலியை எழுப்ப வேறு வழி இல்லை. relay-ஐ நீக்குவதற்கான ஒரே வழி, உங்கள் சொந்த Apple developer கணக்கு மற்றும் APNs keys-ஐப் பயன்படுத்தி iOS செயலியை நீங்களே உருவாக்கி வெளியிடுவதுதான். இதற்கு வருடாந்திரக் கட்டணம் செலுத்த வேண்டும் மற்றும் ஒவ்வொரு update-க்கும் செயலியை மீண்டும் உருவாக்க வேண்டும். இந்த relay முறை உங்கள் பயன்பாட்டிற்கு ஏற்புடையதாக இல்லையென்றால், Android அல்லது desktop web app-ல் அறிவிப்புகளைப் பெறுவதைத் தொடரவும்.

Backups, upgrades and pinning the image

/etc/ntfy/server.yml மற்றும் /var/lib/ntfy/user.db ஆகிய இரண்டு கோப்புகளை மீண்டும் உருவாக்க முடியாது. இரண்டாவது கோப்பில் அனைத்து பயனர்கள், password hash-கள், ACL பதிவுகள் மற்றும் token-கள் உள்ளன, எனவே இதை ஒரு private key-ஐப் போலவே பாதுகாப்பாகக் கையாளவும்.

sudo tar czf ntfy-backup.tgz -C / etc/ntfy var/lib/ntfy
sudo chmod 600 ntfy-backup.tgz

அந்தக் கோப்பை server-லிருந்து நகலெடுத்து வெளியே சேமிக்கவும். cache.db-ல் சமீபத்திய செய்திகள் மட்டுமே உள்ளன, மேலே உள்ள cache-duration அமைப்பின்படி 12 மணிநேரத் தரவு மட்டுமே அதில் இருக்கும், எனவே அதை இழப்பதால் பெரிய பாதிப்பு ஏதுமில்லை. Upgrading என்பது compose file-ல் உள்ள tag-ஐ மாற்றிவிட்டு, புதிய image-ஐ pull செய்வதாகும்.

sudo docker compose pull
sudo docker compose up -d
curl -s https://ntfy.example.com/v1/health

முதலில் release notes-ஐப் படிக்கவும். SQLite databases தொடங்கும்போதே தானாகவே migrate ஆகிவிடும், எனவே schema மாற்றத்திற்குப் பிறகு பழைய tag-க்கு திரும்புவது (rolling back) பாதுகாப்பானது அல்ல. புதிய பதிப்பு ஒரு நாள் முழுவதும் சரியாக இயங்கும் வரை, நீங்கள் எடுத்த backup-ஐ வைத்திருக்கவும்.

Gotify மற்றும் Apprise

Gotify ஒரு சிறிய விருப்பமாகும்: இது ஒரு binary கோப்பு, web UI மற்றும் Android app ஆகியவற்றைக் கொண்டது. இதில் topic wildcards வசதி இல்லை மற்றும் அதிகாரப்பூர்வ iOS client கிடையாது; எனவே, Android மட்டுமே பயன்படுத்தப்படும் ஒரு private server-க்கு இது பொருத்தமானது. Apprise என்பது ஒரு server அல்ல, இது ஒரு Python library மற்றும் command line tool ஆகும். இது ntfy உட்பட நூற்றுக்கும் மேற்பட்ட சேவைகளுக்கு ஒரே செய்தியை அனுப்பும் (fan-out) வசதி கொண்டது; எனவே, ஒரே நேரத்தில் பல இடங்களுக்குச் செய்தி அனுப்ப வேண்டிய script-களுக்கு இது ஏற்றது. ntfy என்பது server, HTTP API மற்றும் இரு மொபைல் தளங்களிலும் இயங்கும் app-களைக் கொண்ட ஒரு முழுமையான தீர்வாகும். இதனால்தான், வாடகைக்கு எடுக்கப்பட்ட server-களில் இருந்து எச்சரிக்கைகளை (alerting) அனுப்ப இது பொதுவாகப் பயன்படுத்தப்படுகிறது.

FAQ

எனது ntfy server-க்கு publish செய்யும்போது ஏன் 403 பிழை வருகிறது?

auth-default-access: "deny-all"-ஐ server.yml-ல் பயன்படுத்தும்போது, anonymous publish நிராகரிக்கப்படும்; இதுவே அதன் இயல்பான செயல்பாடாகும். -u user:pass அல்லது -H "Authorization: Bearer tk_..." மூலம் credentials-ஐ அனுப்பவும். நீங்கள் ஏற்கனவே token-ஐ அனுப்பியும் 403 பிழை வந்தால், அந்த token-க்கு உரிய பயனர் அந்த topic-க்கான ACL அனுமதி பெறவில்லை என்று அர்த்தம். முழு பட்டியலையும் பார்க்க ntfy access கட்டளையை இயக்கவும். write அனுமதி என்பது subscribe செய்வதற்கு வழிவகுக்காது என்பதை நினைவில் கொள்க; எனவே, ஒரு account publish செய்ய அனுமதிக்கப்பட்டாலும், அதே topic-ஐ வாசிக்க முயலும்போது அது நிராகரிக்கப்படலாம்.

சுய-நிர்வாக (self-hosted) ntfy server மூலம் iPhone-ல் அறிவிப்புகள் (notifications) வேலை செய்யுமா?

அவை வேலை செய்யும், ஆனால் தவிர்க்க முடியாத ஒரு relay வழியாகவே இது நடக்கும். Apple தனது APNs (Apple push notification service) வழியாக மட்டுமே apps-ஐ எழுப்பும்; அதன் publisher-ஆல் மட்டுமே அதற்கு அனுப்ப முடியும். எனவே, ntfy ஒரு poll_request-ஐ ntfy.sh-க்கு அனுப்பும், அது அங்கிருந்து device-க்கு relay செய்யப்படும். upstream-base-url: "https://ntfy.sh"-ஐ server.yml-ல் அமைத்து, container-ஐ restart செய்யவும். செய்தியின் உள்ளடக்கம் உங்கள் server-லிருந்தே பெறப்படும். இந்த அமைப்பு இல்லையெனில், iOS அறிவிப்புகள் தாமதமாகும் அல்லது வராது.

எனது cron job மூலம் அனுப்பப்படும் ntfy அறிவிப்பு ஏன் வரவில்லை?

முதலில் curl வரியை மட்டும் தனியாக இயக்கி, token மற்றும் topic சரியாக உள்ளதா என்பதை உறுதிப்படுத்தவும். அது கைமுறையாக இயங்கி, cron-ல் இயங்கவில்லை என்றால், சிக்கல் cron-ன் சூழலில் உள்ளது: cron மிகக் குறைந்த environment மற்றும் குறுகிய PATH-உடன் இயங்கும். எனவே, ஒரு கட்டளையை அதன் பெயரால் மட்டும் அழைக்கும் script, curl வரியை அடையும் முன்பே நின்றுவிடலாம். முழுமையான பாதைகளை (absolute paths) பயன்படுத்தவும், job-ன் வெளியீட்டை ஒரு log file-க்கு redirect செய்து, அடுத்த முறை இயங்கிய பிறகு அந்த file-ஐ வாசிக்கவும். அறிவிப்பு சேர்வதற்குப் பதிலாக 429 பதில் கிடைத்தால், rate limit செயல்படுகிறது மற்றும் உங்கள் script மிக வேகமாக மீண்டும் மீண்டும் முயல்கிறது என்று பொருள்.

ntfy-ஐ பொது இணையத்தில் (public internet) வெளிப்படுத்த வேண்டுமா?

Mobile networks-லிருந்து phone apps அதை அணுக வேண்டியிருப்பதால், auth-default-access: "deny-all" மற்றும் topic-வாரியான ACL-களுடன் கூடிய public HTTPS endpoint-ஐ அமைப்பதே வழக்கமான முறையாகும். எந்தவொரு topic-ம் everyone மூலம் வாசிக்கப்படாமல் இருக்கும் வரை இது பாதுகாப்பானது. அனைத்து subscriber-களும் உங்கள் கட்டுப்பாட்டில் உள்ள machines-ஆக இருந்தால், VPN-மட்டும் கொண்ட instance-ஐப் பயன்படுத்துவது சிறந்தது. இது phone-களுக்குப் பொருத்தமற்றது, ஏனெனில் tunnel இணைப்பில் இருக்கும்போது மட்டுமே app அறிவிப்புகளைப் பெறும்; எனவே, phone மீண்டும் இணையும் வரை அறிவிப்புகள் queue-வில் இருக்கும்.