mysurik.ru

ntfy: уведомления на телефон со своего сервера

Я перепробовал кучу способов получать уведомления с сервера. Pushover — платный. Telegram — нужно бота создавать, токены хранить, следить чтобы бот не забаннили. Email — ну серьёзно, кто сейчас читает почту от сервера? У меня за месяц накопилось тысяч пять писем от cron, я перестал их открывать после первой недели. А потом я нашёл ntfy, и это было как глоток свежего воздуха.

Ntfy — это минималистичный сервер пуш-уведомлений, который ты поднимаешь сам у себя. Кидаешь на него HTTP-запрос, он шлёт пуш на телефон. Всё. Никаких регистраций, никаких сторонних сервисов, никаких ключей API. Свой сервер — свои правила. Единственное требование — у тебя должен быть домен или статический IP для аплинка, но через Tailscale тоже работает отлично.

Установка и настройка

Поднимается в Docker за 30 секунд. Буквально:

docker run -d --name ntfy 
  -p 2586:80 
  -v /path/to/ntfy:/var/lib/ntfy 
  -e TZ=Europe/Moscow 
  binwiederhier/ntfy

Я повесил его за nginx reverse proxy с let’s encrypt-сертификатом, чтобы было по HTTPS. Без HTTPS мобильные приложения ntfy работать отказываются — это не баг, а фича безопасности.

Дальше — базовое администрирование. Создал пользователя, подписался на топик:

docker exec ntfy ntfy user add --role=admin mysurik
docker exec ntfy ntfy token add mysurik mytopic

Можно использовать пароли, но я предпочёл токены — их проще менять и отзывать. Токен передаётся в заголовке Authorization: Bearer при отправке сообщения.

Интеграция с сервером

Первым делом я прикрутил ntfy к cron. Когда бекап Proxmox завершается (или, что бывает чаще, падает с ошибкой), я получаю пуш на телефон. Сделал простой скрипт-обёртку:

#!/bin/bash
NTFY_URL="https://ntfy.mysurik.ru/backups"
NTFY_TOKEN="tk_ваштокен"
if [ $? -eq 0 ]; then
  curl -H "Authorization: Bearer $NTFY_TOKEN" 
       -H "Title: ✅ Backup OK" 
       -H "Priority: low" 
       -d "Backup of $(hostname) completed at $(date)" $NTFY_URL
else
  curl -H "Authorization: Bearer $NTFY_TOKEN" 
       -H "Title: ❌ Backup FAILED" 
       -H "Priority: high" 
       -H "Tags: warning" 
       -d "Backup FAILED on $(hostname)! Check logs!" $NTFY_URL
fi

Потом прикрутил Fail2ban — когда банят IP, я вижу на телефоне кто и откуда ломился. Для Zabbix тоже есть интеграция через webhook — алерты приходят не на почту, а сразу в карман. Пробовал Grafana — через Alertmanager вебхуки работает без проблем.

Ещё настроил отправку уведомлений о состоянии дисков (S.M.A.R.T. через smartd), о переполнении логов (logwatch), о обновлениях пакетов (unattended-upgrades). Каждый сервис пишет в свой топик — я подписан на все, но на телефоне могу отфильтровать по топику или приоритету.

Клиент на телефоне

На телефоне поставил официальное приложение ntfy из F-Droid (в Google Play оно тоже есть). Работает через Firebase Cloud Messaging как fallback, но если сервер доступен напрямую — идёт прямое соединение через WebSocket. Сообщения приходят мгновенно, задержка меньше секунды.

Можно настроить приоритеты: критические уведомления с вибрацией и звуком, информационные — тихо в шторку. Я настроил так: бекапы и алерты Zabbix — высокий приоритет, автообновления пакетов — низкий. В итоге телефон не дёргается по пустякам, но важное не пропускает.

Настройки уведомлений хранятся на сервере — при смене телефона достаточно залогиниться в приложении, и все настройки подтянутся автоматически. Очень удобно, когда переустанавливаешь прошивку или меняешь устройство.

Продвинутые фичи

Ntfy умеет не только текст. Можно передавать заголовки, теги, приоритеты, URL и даже изображения. Я, например, настроил отправку скриншотов с камеры наблюдения при детекте движения (frigate + curl с attachment картинки). Ещё можно прикреплять файлы — логи, скриншоты, CSV.

Отдельно радует, что можно публиковать сообщения анонимно (если не включена аутентификация) — это удобно для одноразовых скриптов, где хранить токен не хочется. Но я всё-таки включил базовую аутентификацию, чтобы любой желающий с интернета не мог слать мне уведомления.

Ещё одна крутая фича — ntfy умеет работать как email-шлюз. Я настроил postfix на пересылку писем от сервера в ntfy через pipe transport. Теперь все письма от system, отчеты Logwatch и сообщения от mdadm приходят на телефон как пуши. Никаких почтовых ящиков для мониторинга — всё в одном месте.

Что не понравилось

Из минусов — нет ретроспективы. Если интернет упал или телефон был выключен, уведомления просто теряются. Ntfy не умеет доставлять пропущенные сообщения — это архитектурное ограничение протокола. Для некритичных уведомлений это нормально, но для критических алертов я дублирую через SMS (есть сервис-прослойка, который шлёт SMS при недоставке пуша).

Второй минус — нет встроенного дашборда. Хочется иногда посмотреть историю уведомлений за неделю, но веб-интерфейс показывает только последние сообщения. Для дашборда можно использовать ntfy + Prometheus/Grafana, но это дополнительная морока.

Третий — если отправлять много уведомлений, база данных ntfy растёт. По умолчанию он хранит всё. Я настроил TTL в конфиге (message-ttl: 72h) и автоочистку раз в час. Так база не раздувается.

Итог

Ntfy стал моей стандартной шиной уведомлений. Я забыл про почтовые ящики для логов. Всё важное — сразу в карман. Поставил на свой сервер, один раз настроил — и забыл. Точнее, помнишь только когда приходит пуш: «Бекап успешен» — и можно спать дальше.

Если у тебя есть свой сервер и ты ещё не поставил ntfy — очень рекомендую. Минимум усилий, максимум пользы. Из всех self-hosted решений, которые я пробовал, ntfy — одно из тех, что реально меняет повседневную работу с сервером. Установка занимает пять минут, интеграция с чем угодно — через curl. Дешевле и проще не бывает.

Установка, о которой я не рассказал в начале. Если честно, первый раз я поставил ntfy как-то наспех — просто docker run с дефолтными настройками. Работало, но я не понимал, куда смотреть и как всё устроено. Второй раз я подошёл осознанно и теперь делюсь деталями, которых не хватало мне.

Во-первых, база данных. По умолчанию ntfy хранит всё в SQLite в /var/lib/ntfy. Для дома — нормально. Но если уведомлений много, стоит присмотреться к очистке. Я включил TTL 72 часа и периодическую чистку, и база держится в паре сотен мегабайт. Есть вариант перевести на Redis — но это уже для больших инсталляций, дома незачем.

Во-вторых, правильные заголовки. Многие ограничиваются простым curl -d «текст» и теряют кучу возможностей. Вот несколько заголовков, которые я использую каждый день:

curl -H «Priority: urgent» -H «Tags: warning» -H «Title: ВАЖНО» -H «Click: https://mysurik.ru» -d «Текст» https://ntfy.mysurik.ru/topic

Priority — от min до urgent. Tags — эмодзи-метки (warning, alert, server и десятки других). Click — по клику открывает нужный URL. Всё это делает уведомление не просто текстом, а полноценной карточкой с действиями. Когда приходит пуш «Бекап упал» и по клику открывается панель Proxmox — это уровень совершенно другого комфорта, чем голый текст.

В-третьих, защита доступа. Мне важно, чтобы чужие не могли писать в мои топики. Я включил аутентификацию и создал отдельные токены на каждый сервис. Так, если какой-то скрипт скомпрометируют — отзову только его токен, а не весь сервер. Команда отзыва:

docker exec ntfy ntfy token revoke mysurik bad_token

Забыл упомянуть ещё одну вещь: политику доступа можно настроить тонко. У меня один топик для скриптов-«анонимов», куда можно писать без токена (для тестовых запусков), и закрытые топики для всего важного. Это удобно, когда ковыряешься в новой автоматизации и не хочется каждый раз вставлять токен.

Как это у меня выглядит в связке с остальным стеком. Вся шина уведомлений собралась сама собой: Cron и systemd-таймеры шлют статус бекапов, smartd — состояние дисков, fail2ban — баны, unattended-upgrades — обновления. Плюс Zabbix через webhook и Grafana через Alertmanager. Все они пишут в свои топики, а я в приложении настроил группы: «Сервер», «Бекапы», «Безопасность». Телефон не дёргается от всего подряд — только от приоритетных.

Что важно понимать про доставку. Ntfy не гарантирует доставку, если клиент был офлайн — сообщения не накапливаются бесконечно. Поэтому для критичных алертов я оставил SMS-дублёра через прокси-сервис: если пуш не доставлен в течение пары минут, приходит SMS. Это перестраховка, но для меня она важна — сервер стоит дома, и если дома пропал интернет, я должен узнать об этом, даже не имея сети на телефоне.

Ещё пара слов про мобильный клиент. Приложение умеет показывать последнее сообщение в топике сразу на экране подписки — не нужно открывать его. Есть встроенный просмотр вложенных изображений. И главное — подписки можно открыть по ссылке или QR-коду, что удобно, когда нужно быстро дать доступ жене или коллеге.

Вердикт после месяцев использования. Ntfy — это тот инструмент, который я ставлю на каждый новый сервер первым делом, ещё до мониторинга. Потому что без уведомлений любой мониторинг бесполезен — ты просто не узнаешь, что что-то упало. Пять минут на установку, десять — на базовые интеграции, и вся серверная инфраструктура начинает разговаривать с тобой напрямую. Не через почту, не через десяток приложений, а в одно место — на телефон. Если у тебя ещё нет своей шины уведомлений — начни с ntfy. Дешевле, проще и надёжнее варианта я не нашёл.

Ещё одна фишка, которую я полюбил — темплейты через webhook в Home Assistant. Когда в умном доме что-то случается (открыта дверь, сработал датчик протечки, закончился Wi-Fi у розетки) — всё прилетает в ntfy. Настроил один раз через REST-интеграцию в Home Assistant и забыл. Кстати, сценарий из статьи про умные розетки у меня как раз завязан на ntfy: если чайник включился, но через час не выключился — я получаю алерт. Раньше приходилось заходить в панель и смотреть вручную.

Интересный момент — ntfy поддерживает карточки с кнопками действий на iOS и Android. То есть уведомление может содержать кнопку «Выполнить» или «Открыть». Для скриптов, которые требуют подтверждения, это превращает пуш в полноценный пульт управления. Я, например, настроил кнопку перезапуска контейнера прямо в уведомлении об ошибке: увидел, что сервис упал, ткнул кнопку — и он поднялся. Правда, реализовал это через дополнительный webhook, но эффект стоит того.

А если говорить про надёжность — важно ставить ntfy в отдельном контейнере с рестартом. У меня он живёт в docker-compose с ограничением памяти и автоматическим перезапуском. Один раз контейнер упал из-за разросшейся БД, и я несколько часов не получал уведомлений — заметил только когда сам полез в панель. После того как поставил TTL и лимит памяти, такое не повторялось. Урок простой: шина уведомлений сама должна быть надёжной, потому что все остальные системы от неё зависят.

Ваш комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *