news 2026/9/9 16:25:48

自建ntfy推送服务:从部署到实战的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
自建ntfy推送服务:从部署到实战的完整指南

简介:这是一款基于 Go 语言开发的轻量级推送通知工具 ntfy,面向需要向手机或桌面实时推送消息的开发者和运维人员。它通过简洁的 PUT/POST 请求即可触发通知,适用于服务报警、脚本执行提醒、定时任务状态推送、IoT 事件通知等场景,省去自行搭建消息通道的麻烦。资源包共包含 415 个文件,压缩后约 12.89MB,主要涵盖 106 个 Go 源码文件、前端界面常用的 js/jsx/css、png/svg/ico 图标与图片素材,以及 Dockerfile、配置文件、说明文档等,目录结构清晰,便于按需查阅与二次开发。目前已有 1658 人学习下载,受到较多开发者关注。对自建通知服务或研究 Go 工程实践的读者而言,这份资源提供了可运行的服务端源码、Web 管理界面、容器化部署方案和移动端接入示例,覆盖从部署到调用的完整链路,既能直接用于生产环境,也可作为项目学习参考。

1. 为什么我弃了一堆商业推送,最后留下了 ntfy

做运维和自托管这行久了,通知推送这个事儿绕不过去。服务器报警要通知,脚本跑完要通知,下载任务结束要通知,CI/CD 构建结果也要通知。前前后后我试过 Telegram Bot、Server酱、Pushover、Bark 这些方案,各有各的问题。第三方服务要么有消息频率限制,要么依赖外部网络状况,要么就是客户端体验不够顺手。直到我用上了 ntfy,才觉得这个事儿终于清爽了。

ntfy(读作 notify)是一个开源的、基于 HTTP 的推送通知服务,核心思路特别朴素:你往一个 URL 发一条 HTTP 请求,订阅了这个主题的设备就能立刻收到推送。它支持手机 App、桌面浏览器、命令行工具等多种订阅方式,可以自己部署,也可以用官方公共实例 ntfy.sh。对我来说,最吸引人的是两件事:一是自托管之后数据完全在自己手里,二是对接方式极其简单,curl 一条命令就能发通知,比什么 SDK、API 封装都来得直接。

这篇文章写给谁?如果你有服务器、NAS、树莓派,或者你平时写脚本跑自动化任务,想找一种“一旦有事能立刻叫醒你”的通知方式,那 ntfy 很适合你。就算你是零基础用户,只想来个简单的手机推送,照着文章里最简单的方式也能搞定。我尽量把部署、配置、避坑这些实操细节都讲透,都是自己踩过之后沉淀下来的经验。

1.1 一次需求变化让我重新审视推送工具

最初我用的是某商业推送服务,绑定 App 之后往里发请求就行。一开始还挺满意,后来有次服务器凌晨宕机,报警消息因为对方服务限流被丢了,第二天一早我才发现网站挂了几个小时。那次之后我就决定,通知链路必须自建,不能把命脉掐在别人手里。

选型时我列了这几个硬性要求:部署足够简单,最好一个容器搞定;API 足够通用,任何语言都能调;客户端体验要好,推送延迟要低;最好还支持权限控制,不至于裸奔在公网上。逐个筛下来,ntfy 几乎完全命中。它服务端是 Go 写的单二进制文件,部署几乎没有依赖,数据库用的是 SQLite,缓存消息也不需要额外装 Redis。客户端覆盖 Android、iOS、Web、桌面,还支持命令行订阅,一条命令就能在终端里收消息。

1.2 HTTP + Topic 的思路到底精妙在哪

ntfy 最核心的抽象是“主题”(Topic),你可以把它理解成一个微信群聊的群名。发布者往这个主题发消息,订阅者就会收到。它的 API 就是普通 HTTP,比如:

curl -d "服务器磁盘空间不足" ntfy.sh/myserver-alerts

就这么一行,任何能发 HTTP 请求的工具,都成了你的通知发送器。没有 SDK 的繁琐,不用引入依赖,也不限制编程语言。我的脚本里直接curlpython requestsNode fetch都试过,全部畅通。这套设计的新颖之处在于:它把推送这个“应用层能力”降维成了“HTTP 请求”,让任何终端都能轻松对接。

1.3 和其他方案的直观对比

我顺手整理了一个对比表,方便你判断自己的需求落在哪儿:

方案部署方式接入成本客户端体验适合场景
ntfy自托管,单容器极低,curl即可Android/iOS/Web/桌面全支持自托管爱好者、开发者
Telegram Bot官方服务较低,需要外网访问官方App体验好能接受依赖第三方服务
Server酱官方服务极低,微信接收依赖微信国内快速接入
Bark自托管或公共实例较低,iOS专用仅iOS苹果生态用户

如果你追求可控性和通用性,ntfy 的优势非常明显。如果你的需求是一次性接个微信提醒,那 Server酱也许更省事。工具没有绝对好坏,合适才最重要。

2. 自建 ntfy 服务:部署与基础配置

我用 Docker 部署,这是目前为止最省心的方式。以下是我的实际部署过程,包含配置细节和一些容易忽略的坑。

2.1 Docker 快速部署

先创建一个数据目录,用于持久化配置和缓存:

mkdir -p /opt/ntfy/data mkdir -p /opt/ntfy/etc

然后写一个简单的docker-compose.yml

version: "3" services: ntfy: image: binwiederhier/ntfy:latest container_name: ntfy command: - serve environment: - TZ=Asia/Shanghai volumes: - /opt/ntfy/data:/var/lib/ntfy - /opt/ntfy/etc:/etc/ntfy ports: - "8080:80" restart: unless-stopped

启动:

docker compose up -d

注意几点。第一,镜像里的默认端口是 80,我映射到宿主机的 8080,避免和已有服务冲突。第二,/var/lib/ntfy是数据目录,消息缓存和用户数据库都存在这里,必须持久化,否则容器重建消息全丢。第三,环境变量里我设置了时区,以后消息时间显示会正常。

服务起来后,浏览器访问http://你的服务器IP:8080,能看到 ntfy 的 Web 界面就说明成功了。

2.2 关键配置项解析与踩坑点

ntfy 的配置主要写在/etc/ntfy/server.yml里。先给几个我实际用到的配置项:

# 外部访问的基础URL,务必改成你的实际域名或IP base-url: "http://your-domain.com" # 监听地址,默认监听所有网卡 listen-http: ":80" # 消息缓存文件 cache-file: "/var/lib/ntfy/cache.db" # 缓存消息条数 cache-messages: 5000 # 消息在没有订阅者时是否缓存,等订阅者上线再推 cache-duration: "12h" # 是否开启用户注册功能 auth-default-access: "deny-all" enable-signup: false

这里我踩过一个坑:base-url如果配错,手机 App 扫码后连接会失败,提示地址不对,但服务端日志里一切正常。这个问题很隐蔽,排查了我半小时。提醒你,配置修改后要重启容器生效:

docker compose restart

2.3 添加访问控制和用户体系

服务部署完了,最重要的事就是加权限。初始状态下 ntfy 是允许所有人读写的,就像群里所有人都能发消息,这在公网上等于裸奔。好在 ntfy 天然支持基于用户和 Access Control List(ACL)的权限控制。

先创建一个管理员用户:

docker exec -it ntfy ntfy user add --role=admin myadmin

然后设置密码,按提示输入两次即可。接着创建普通用户,每个用户对应一组主题权限:

docker exec -it ntfy ntfy user add alert-user docker exec -it ntfy ntfy access allow alert-user write-only 'server-alerts'

上面这条命令的意思是,alert-user只能向server-alerts主题写消息,不能读取。这个场景对应你的监控系统:它只需要发,不需要收。同理,你自己作为个人用户,可能需要某个主题既能读又能写:

docker exec -it ntfy ntfy access allow myuser read-write 'my-notes'

配置好之后,往受保护的主题发消息就需要认证了,格式为https://ntfy.example.com/主题名,请求头加上:

curl -H "Authorization: Bearer tk_你的访问令牌" -d "hello" https://ntfy.example.com/server-alerts

访问令牌可以通过 Web 界面生成,也可以在命令行里用ntfy token add命令创建。这种方式比直接用密码更安全,适合脚本环境,因为令牌可以单独撤销,不用改密码。

3. 手机和桌面的接入与日常玩法

部署好了服务端,接下来就是各种端上的接入。这一部分是普通用户最容易卡住的地方,我详细拆开讲。

3.1 手机端 App 安装配置

Android 端在 F-Droid 或者 Google Play 搜 ntfy 就能装。iOS 端在 App Store 搜索 ntfy 即可。安装后打开 App,点击右上角的设置图标,进入“设置”页面,找到“服务器地址”一栏,填写你自建服务的地址,比如https://ntfy.example.com

然后回到主界面,点击“添加订阅”,输入主题名称,比如server-alerts。如果你在服务端配置了权限,还需要在“用户名/密码”或者“访问令牌”里填上对应的凭证。一切正常的话,App 会显示“已连接”,之后对应的推送就都能收到了。

这里有一个 Android 特有的坑:部分国产手机系统为了省电,会自动杀掉后台 App,导致推送延迟甚至完全收不到。你需要把 ntfy 加入电池优化的白名单,并在系统设置里允许它自启动。iOS 端因为是走 APNs,后台问题少很多,但也要保证 App 的通知权限是开启的。

3.2 桌面端与浏览器的接入方式

桌面端其实不用装什么重量级客户端。ntfy 提供了一个 Web 界面,你直接在浏览器里打开服务器地址,登录后能看到所有订阅的主题,也能在网页上发消息。这个方案对我这种经常在不同电脑之间切换的人来说最舒服,浏览器开着就能收,不用装软件。

如果你在终端里办公多,ntfy 还有命令行客户端。安装方式:

curl -sSL https://github.com/binwiederhier/ntfy/releases/latest/download/ntfy_linux_amd64.tar.gz | tar -xz sudo mv ntfy /usr/local/bin/

之后订阅主题:

ntfy subscribe --user=myuser:pass https://ntfy.example.com/server-alerts

命令行订阅主要用于调试,或配合 tmux 在后台常驻接收消息。

3.3 实用玩法:从监控告警到自动化提醒

服务跑起来、客户端接好了,玩法就多了。我这里列几个我自己常用的场景,你可以参考着改造。

第一,服务器监控告警。配合 Uptime Kuma 或 Zabbix,把 webhook 地址填成https://ntfy.example.com/server-alerts,在请求头里加上认证令牌。我自己的服务器 CPU 过载、磁盘不足、服务宕机,都是通过这个链路第一时间收到推送。

第二,脚本执行结果通知。比如每天凌晨的数据库备份任务,备份成功、失败都发一条到backup-status主题,我早上起床一翻手机就知道昨晚备份有没有问题。脚本里一行 curl 就够了:

curl -H "Authorization: Bearer tk_xxx" \ -H "Title: 数据库备份" \ -H "Priority: default" \ -d "备份成功,耗时 3 分 20 秒" \ https://ntfy.example.com/backup-status

第三,下载任务完成通知。我用的是 qBittorrent 的 Webhook 功能,下载完成后往downloads主题发一条消息,带上文件名和保存路径,省得每天刷客户端看进度。

第四,智能家居联动。如果你用 Home Assistant,直接在自动化里调用 REST API 就能往 ntfy 发消息,比如“门锁已打开”“烟雾报警器触发”,比折腾各种专用推送组件省事得多。

4. 常见问题与排查技巧实录

实践多了总会遇到各种问题,我把我遇到过的、以及朋友踩过的一些坑整理成速查表,希望能帮你少走弯路。

问题现象可能原因解决方案
手机收不到消息,但 Web 界面正常系统后台优化杀掉 App加入电池白名单,允许自启动
收不到消息,服务端日志没有请求防火墙没放行端口检查 80/8080 端口是否开放
App 订阅时提示连接失败base-url配置错误或 HTTPS 证书问题检查 server.yml 的 base-url,访问域名是否 HTTPS
发消息提示 401权限配置有问题或令牌无效检查用户权限和令牌是否对应
消息延迟严重网络问题或 App 被省电策略限制检查网络,调整系统电池策略
重启容器后历史消息丢失数据目录没有挂载持久化确认 volumes 配置正确

4.1 收不到消息的排查顺序

遇到收不到消息,我一般按这个顺序排查:先看服务端日志,docker logs ntfy有没有请求记录;再看客户端能否正常连接服务器;接着看是不是走了代理或 HTTPS 证书有问题;最后查手机系统设置。大部分问题都出在最后两步,尤其是国产手机的系统省电策略,这属于“非技术性”问题,但也是最容易让人崩溃的。

4.2 公网暴露的防护建议

如果你打算把 ntfy 暴露到公网,我强烈建议加一层反向代理,并用 HTTPS 加密传输。我自己是用 Caddy 简单配置的,Caddy 会自动申请和续期证书:

ntfy.example.com { reverse_proxy 127.0.0.1:8080 }

这样外部访问就是https://ntfy.example.com,证书自动搞定。另外别忘了在防火墙层面仅放行 80、443 端口,ntfy 的 8080 只允许本机访问,避免绕过代理直接裸奔。

还有一点,如果你用的是默认配置且开了注册功能,公网上任何人都能注册用户,既浪费资源又有安全隐患。建议像我一样,把enable-signup设为false,用户全部用命令行创建,权限按需分配。

4.3 消息延迟与缓存机制

ntfy 默认会缓存一段时间的消息,好处是:如果手机暂时离线,等它上线后能收到缓存期间错过的消息。缓存时长和条数都可以在 server.yml 里调整。我设置的是 12 小时、5000 条,对日常使用完全够用。注意,缓存不是永久存储,如果你需要消息长期留存,建议同时对接一个日志系统,比如直接把消息写入文件或数据库。

延迟方面,我用自建服务实测下来,手机推送延迟基本在 1 秒内,有时候甚至感觉是即时到达。这点比某些“定时轮询”的方案体验好很多,也是我一直用它作为主力通知工具的重要原因。

4.4 一个小经验:先跑通最小链路

最后分享一个我在接入任何新工具时都会用的经验:先跑通最小链路,再扩展功能。所谓最小链路,就是服务端部署好之后,先在终端用 curl 发一条消息到某个主题,同时手机 App 订阅这个主题,确认能收到。这一步通了,说明基础设施没问题。之后再逐步添加权限、反向代理、HTTPS、多用户、自动化脚本,每加一块就测试一块,定位置永远是最小的问题域,排查效率高很多。

我最初就是从 curl 发消息、手机收消息这一步开始的,整个过程前后不到 10 分钟。后来才慢慢加上 HTTPS、权限控制、监控告警和各类自动化脚本。到现在,ntfy 已经成了我日常运维里最离不开的基础设施之一。按这个思路走,你也能快速搭起一套自己的推送中枢。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/9 16:25:42

Overleaf上手指南:免费学术排版的零门槛实战

Overleaf上手指南:免费学术排版的零门槛实战 【免费下载链接】overleaf A web-based collaborative LaTeX editor 项目地址: https://gitcode.com/GitHub_Trending/ov/overleaf 论文截稿前夜,本地LaTeX编译报错,你盯着终端一行行找依赖…

作者头像 李华
网站建设 2026/9/9 16:23:38

ISAC多域优化:电磁成形与网络协作的交替迭代框架

ISAC(Integrated Sensing And Communication,通信感知一体化)最近在无线通信圈子里热度一直没下来过,尤其到了5G-A和6G预研阶段,几乎每个做物理层和网络层的团队都在往这个方向靠。说白了,ISAC的核心诉求就…

作者头像 李华
网站建设 2026/9/9 16:21:05

用Open Generative AI三步搭建自己的免费AI图片视频工作室

用Open Generative AI三步搭建自己的免费AI图片视频工作室 【免费下载链接】Open-Generative-AI Unrestricted Open-source alternative to AI video platforms — Free AI image & video generation studio with 600 models (Flux, Midjourney, Kling, Sora, Veo). No con…

作者头像 李华
网站建设 2026/9/9 16:17:11

GeckoDriver 完全解析:原理、配置、实战与高频报错排查

做 Web 自动化测试的人,几乎都绕不开 Selenium。但很多新手在第一次用 Firefox 跑脚本时都会卡在同一个地方:明明 Selenium 装好了,Firefox 也装好了,一运行就报WebDriverException: Message: geckodriver executable needs to be…

作者头像 李华