Индекс на дневникаDockup / бележка от практиката
Note / self-host-ntfy

Как да хоствате ntfy самостоятелно през 2026 г.: теми, контрол на достъпа и доставяне

Практическо ръководство за самостоятелно хостване на ntfy с Docker, портове, постоянни данни, TLS, сигурност, резервни копия и проблемите, които пречат на използването му в production. Стъпка по стъпка.

Повечето бележки за инсталиране на ntfy приключват при първото зареждане на страницата. Това е твърде рано: cache-ът е ефимерен или връзките WebSocket/SSE прекъсват поради изтичане на timeout-а в proxy сървъра. Полезният production тест е по-взискателен — публикувайте съобщение с curl, получете го чрез HTTP и WebSocket subscriptions, прикачете файл и тествайте една автентикирана тема.

Ролята на ntfy е ясна: изпращане на push известия с проста HTTP заявка. Оперативният му обхват включва повече от web процеса, затова зависимостта, съхраняваното състояние и публичният route трябва да бъдат описани изрично, преди да постъпят реални данни.

Production архитектурата на ntfy

HTTP процесът на ntfy слуша на порт 80; оставете този порт в application network и публикувайте само route-а на платформата. Локалното изискване за runtime е config volume и опционална auth database. Тествайте тази граница преди публикуване и отново след замяна на container.

Опишете границата като кратък договор: кой отговаря за изискването, кои credentials се използват, какъв timeout е приемлив и как изглежда повредата. След това изпълнете тази транзакция: публикувайте съобщение с curl, получете го чрез HTTP и WebSocket subscriptions, прикачете файл и тествайте една автентикирана тема. Наблюдавайте дълготрайните subscriber connections, размера на прикачените файлове, задържането в cache-а и outbound push relay-ите по време на изпълнението, защото това натоварване дава по-полезен начален размер от неактивен container.

Стартирайте ntfy, без да скривате важните детайли

Използвайте container-а като заменяем runtime, а не като място, където се съхранява истината.

docker run -d \
  --name ntfy \
  --restart unless-stopped \
  -p 127.0.0.1:80:80 \
  -v ntfy-data:/var/cache/ntfy \
  -e NTFY_BASE_URL=https://app.example.com \
  binwiederhier/ntfy:latest serve

Потвърдете локалното изискване преди излагане: config volume и опционална auth database. Проверете потребителя на container-а, writable paths и bound listener-а, преди да го изложите. Изпълнете цялото действие — публикувайте съобщение с curl, получете го чрез HTTP и WebSocket subscriptions, прикачете файл и тествайте една автентикирана тема — и запазете точната image reference, с която е получен резултатът.

Дайте на ntfy един каноничен адрес

Задайте base-url към публичния HTTPS origin, използван от publishers и subscribers. Насочете избрания hostname към порт 80 на container-а, препратете оригиналните host и HTTPS scheme и не публикувайте втори директен origin.

Тествайте ntfy от чист външен client. Разделяйте повреда при ingress от познатата application boundary — cache-ът е ефимерен или връзките WebSocket/SSE прекъсват поради изтичане на timeout-а в proxy сървъра. Грешка в сертификата, DNS или 502 принадлежи на routing-а; заявка, която достига до ntfy и се проваля по-късно, принадлежи на application state, capacity или поддържащото изискване. Ръководството за TLS с custom domain разглежда първата група.

Докажете, че ntfy преживява замяна

Защитете state-а на ntfy, преди да оптимизирате container-а. Необходимият набор включва конфигурацията, auth database и прикачените файлове, които трябва да се запазят. Монтирайте /var/cache/ntfy преди bootstrap, запишете безвредни примерни данни и заменете container-а, за да докажете, че този path действително е persistent. Ако няколко store-а трябва да останат съгласувани, документирайте реда, в който спирате записите и създавате backup-ите.

Съхранявайте копия извън deployment сървъра и криптирайте материалите, съдържащи credentials или private content. Възстановяването е успешно, когато users, ACL-ите, конфигурацията и запазените attachments се върнат и автентикиран subscriber получи ново съобщение. Разликата между persistent mount и независимо копие е разгледана в persistent storage и snapshots.

Не давайте на ntfy целия host

При ntfy ценната повърхност не е непременно landing page-ът. Основната грешка е да позволите публично отгатване на теми, когато съобщенията съдържат operational details. Противодействайте умишлено: използвайте topic ACLs, защото неотгатваемите имена на теми не са надеждна authorization за operational messages.

NTFY_BASE_URL е configuration, а не secret; запазете стойността му изрично, като защитите отделните credentials, използвани от ntfy. Използвайте unprivileged container user, когато image-ът го поддържа, и не монтирайте несвързани credentials. Прилагайте rate или size limits на ingress ниво, където непроверена работа може да консумира дълготрайни subscriber connections, размер на attachments, cache retention и outbound push relay-и.

Ъпгрейдвайте ntfy без догадки

Използвайте публикуване на съобщение с curl, получаването му чрез HTTP и WebSocket subscriptions, прикачването на файл и тестването на една автентикирана тема като ntfy smoke test след всяко deployment. Поддържащите му metrics са дълготрайни subscriber connections, размерът на attachments, cache retention и outbound push relay-ите; настройте alerts там, където тези ресурси се доближават до ниво, което влошава потребителското действие.

Основният риск при промяна е, че configuration keys, auth database migrations и очакванията на clients трябва да бъдат проверени, преди да обновите ntfy. Безопасният release започва от snapshot, който може да бъде възстановен, и валидира всяка еднопосочна промяна на state-а, преди трафикът да бъде пренасочен. Когато cache-ът е ефимерен или връзките WebSocket/SSE прекъсват поради изтичане на timeout-а в proxy сървъра, задръжте повредения container достатъчно дълго, за да прочетете конфигурацията му и първата грешка.

Gate за release на ntfy

Release candidate за ntfy получава трафик, след като завърши фиксиран сценарий: публикувайте съобщение с curl, получете го чрез HTTP и WebSocket subscriptions, прикачете файл и тествайте една автентикирана тема. Запишете image digest-а, ефективната non-secret конфигурация, публичния origin и timestamps за този сценарий. Тестовите данни трябва да могат да бъдат изхвърлени, но да са достатъчно реалистични, за да упражнят същия path като потребителите.

Изпълнете го след замяна на runtime-а, след което изградете отново service-а от конфигурацията, auth database и attachments, които трябва да се запазят. Възстановяването е успешно, когато users, ACL-ите, конфигурацията и запазените attachments се върнат и автентикиран subscriber получи ново съобщение. Сравнете измерванията на ресурсите за дълготрайни subscriber connections, размера на attachments, cache retention и outbound push relay-ите с предишния release и проучете значимите отклонения, преди да го промотирате.

Накрая изпълнете този контролиран отказ: изпратете безвреден input близо до resource или format limit-а, свързан с тази граница: cache-ът е ефимерен или връзките WebSocket/SSE прекъсват поради изтичане на timeout-а в proxy сървъра. Проверете дали ntfy обяснява повредата, не поврежда съществуващия state и възобновява работа, след като валидното условие се върне. Запазете редактиран log excerpt и времето за възстановяване. Заедно тези проверки обхващат поведението, durability и operability, а не само uptime-а на процеса.

Поддържайте ntfy изричен, докато Dockup управлява routing-а

Routing-ът, сертификатите, замяната на service-и и attached storage са разумни цели за automation. Dockup ги управлява за ntfy и може да provision-не свързаната managed database или да се свърже със services на собствения сървър на клиента.

Това, което не бива да измисля, е trust policy-то на ntfy. След deployment задайте base-url към публичния HTTPS origin, използван от publishers и subscribers, приложете тази граница — използвайте topic ACLs, защото неотгатваемите имена на теми не са надеждна authorization за operational messages — и проверете резултата от този сценарий: публикувайте съобщение с curl, получете го чрез HTTP и WebSocket subscriptions, прикачете файл и тествайте една автентикирана тема. Резултатът е one-click infrastructure с application-specific acceptance test.

Често задавани въпроси

Какво е необходимо на ntfy за production deployment?

Насочете container-а на ntfy на порт 80 през един HTTPS origin. Локалното изискване за runtime е config volume и опционална auth database. Не обявявайте ntfy за готов, докато не можете да публикувате съобщение с curl, да го получите чрез HTTP и WebSocket subscriptions, да прикачите файл и да тествате една автентикирана тема.

Кои данни на ntfy трябва да бъдат включени в backup?

Направете /var/cache/ntfy persistent и включете конфигурацията, auth database и attachments, които трябва да се запазят, в един и същ recovery manifest. Чистото възстановяване на ntfy е успешно само когато users, ACL-ите, конфигурацията и запазените attachments се върнат и автентикиран subscriber получи ново съобщение.

Нуждае ли се ntfy от HTTPS зад reverse proxy?

Използвайте HTTPS за публичния ntfy origin и оставете порт 80 във вътрешния route. Приложете правилно настройката на ntfy: задайте base-url към публичния HTTPS origin, използван от publishers и subscribers. При ntfy HTTPS защитава credentials или user content при пренос и поддържа последователно поведение на clients, зависещо от origin-а.

Как трябва да се тества ъпгрейд на ntfy?

Възстановете текущия state на ntfy в изолирано deployment, приложете candidate версията и повторете acceptance транзакцията. Обърнете специално внимание, защото configuration keys, auth database migrations и очакванията на clients трябва да бъдат проверени, преди да обновите ntfy. Запазете предишния ntfy image, докато не изясните границите на data migration-а и rollback-а.