gotify/server
更新于 2026-10-21 16:13:50
一句话
gotify/server 是一个自建的推送服务:脚本用 REST 发消息,客户端用 WebSocket 收,Go 写的单二进制(内含 Web UI)。2018 年活到现在,是这个品类里最"老派但没烂"的那一个。
- 仓库:https://github.com/gotify/server | 官网:https://gotify.net
- 规模:16.1k star / 898 fork,MIT,最新 v3.1.1(2026-09-15)
- 配套:Android 客户端(Play Store / F-Droid)、官方 CLI、Go 插件系统、3.x 起内置 MCP 端点
它的模型很清楚:应用发、客户端收、用户管
gotify 把权限拆成三个角色,不理解这个就看不懂它的 token 体系:
| 角色 | 能做什么 | 不能做什么 |
|---|---|---|
| application(应用) | 发消息,拿到一个 app token | 读消息、管理任何东西 |
| client(客户端) | 接收消息、管理自己的客户端 | 发消息 |
| user(用户) | 管理自己创建的 client / application / message | 管别人的 |
这个设计比"一个 token 走天下"干净得多。你给 NAS 备份脚本建一个 application,token 就算泄漏了,最坏结果是别人能往你的推送里灌垃圾,读不到也删不掉任何东西。
发一条消息
# 最简形式
curl "https://gotify.example.com/message?token=<apptoken>" \
-F "title=备份完成" -F "message=耗时 42 分钟,共 3.2G" -F "priority=5"
或者走 JSON(header 带 token):
curl -X POST "https://gotify.example.com/message" \
-H "X-Gotify-Key: <apptoken>" \
-H "Content-Type: application/json" \
-d '{"title":"告警","message":"磁盘 92%","priority":8}'
priority 1–10,数字越大越"吵"(客户端可按等级分组、决定是否响铃)。
还能顺手塞一些渲染提示(extras):
client::display→contentType: text/markdown,消息按 Markdown 渲染client::notification→bigImageUrl(通知里带大图)、click.url(点通知跳转)
收消息靠 WebSocket,不碰 FCM/APNs
这是 gotify 和"云推送"最本质的区别:官方 Android 客户端靠前台服务维持一条 WebSocket 长连接,不依赖 Google 服务框架。
好处:没有 GMS 的机器、去谷歌环境的手机、内网设备都能用,消息不经过任何第三方。
代价(必须提前知道):
- 手机端有一条常驻的"连接状态"前台通知(可以最小化,但去不掉)
- 会被 Android 的电池优化杀,官方文档专门让你去
dontkillmyapp.com按厂商关优化 - 国产 ROM 上漏消息基本是"后台被杀",不是 gotify 的锅,但体验上确实是它的问题
3.x 藏了一个很有用的东西:内置 MCP
v3.1.1 提供 /mcp 端点(Streamable HTTP,无状态,挂反代不用特殊配置),只暴露一个工具 send_message:
claude mcp add gotify --transport http https://gotify.example.com/mcp \
--header "Authorization: Bearer <apptoken>"
参数就是 message / title / priority / markdown / click_url / big_image_url。
两点值得夸:
- 只接受 application token —— agent 只能发,不能读不能删不能管理,权限边界卡死在"通知"这一件事上。
- 可以用
GOTIFY_MCP_ENABLED一键关掉 —— 不需要就彻底不暴露。
这个设计正好卡在 2026 年最真实的需求上:Claude Code / Codex 跑 40 分钟的长任务,跑完或者卡住要你拍板时,往你手机上戳一下。跟 herdr 那种"pane 状态 blocked"是同一层的需求,一个在终端里提醒,一个在手机上提醒。
插件
官方有完整的插件体系:Go 插件编译成 .so,丢进插件目录即可,能在消息进出链路上做加工(改内容、转投别的渠道)。
局限:Go 的 plugin 机制要求插件和服务端同版本、同工具链编译,跨版本升级经常要重编;Windows 上支持也差。想要"随便写个 Python 脚本接进来",那不是 gotify 插件该干的事,写个消费 WebSocket 的小服务更实在。
部署
docker run -p 80:80 -v /var/gotify/data:/app/data gotify/server
多架构镜像覆盖 amd64 / i386 / arm64 / armv7 / riscv64(树莓派、香橙派直接上)。也有 linux/windows 的 zip 二进制(含 RISC-V)。
services:
gotify:
image: gotify/server
ports:
- "8080:80"
environment:
GOTIFY_DEFAULTUSER_PASS: '改掉我'
volumes:
- './gotify_data:/app/data'
/app/data里是 SQLite 库、应用图标和证书,备份就备这个目录- 数据库默认 SQLite,可换 MySQL / PostgreSQL
- 首次登录
admin / admin,第一件事就是改密码 - 反代官方给了 Apache / Caddy / HAProxy / Nginx / Traefik 五套配置,支持 OpenID Connect 登录
和 ntfy 怎么选(重点)
| gotify | ntfy | |
|---|---|---|
| 发送接口 | REST(query token 或 header) | HTTP PUT/POST,topic 就是地址 |
| 接收 | WebSocket | JSON stream / SSE / WebSocket / raw 四选一 |
| 通道模型 | application(发)+ client(收)分离 | topic(发布/订阅同一命名空间) |
| 官方 iOS | ❌ 没有 | ✅ 有(自建有坑,见 ntfy 那篇) |
| 官方 Android | ✅ 不依赖 FCM | ✅ F-Droid 版不依赖 Firebase |
| 消息缓存回放 | 有消息列表,无 since= 语义 |
✅ since=all/10m/<id> 直接补历史 |
| 附件 | ❌ 无上传,只能给图片 URL | ✅ 本地或 S3,带大小限制 |
| 定时投递 / 动作按钮 | ❌ | ✅ delay、actions(按钮) |
| 权限粒度 | 用户 / 应用 / 客户端 | 用户角色 + topic 级 ACL + access token |
| MCP | ✅ 3.x 内置 /mcp |
❌ 需自己包一层 |
| 扩展方式 | Go 插件(版本耦合) | 丰富的第三方集成 |
| 气质 | 一个自建 App Server | 一个 HTTP pub-sub 协议 |
一句话:gotify 更像"自己的推送 App 后端"(有 UI、有用户、有应用管理),ntfy 更像"推送界的 curl"(一个 URL 就是一条通道)。
边界和冷水
- 官方没有 iOS 客户端。社区方案是把 gotify 的 WebSocket 桥到 Bark / ntfy(比如
iGotify那类容器),等于绕一圈。iPhone 用户请直接选 ntfy。 - Android 靠常驻连接,注定漏消息风险。别在"关键告警"场景把它当唯一通道,重要的事配个兜底(邮件/短信)。
- v3 是破坏性升级。官方文档里专门有一页 Migrate to 3.x,老部署升级前先读。
- 迭代偏慢。8 年项目,v3.1.1 是 2026-09 的版本,稳是优点,但别指望它每月上新功能。
- 插件不是"随便挂个脚本"。Go plugin 的版本/工具链耦合是真的难受,重度扩展需求建议直接在 3.x 的 REST + WebSocket 外面写服务。
适合谁
- ✅ 想要一套自带 Web UI、多用户、有应用管理的自建推送(团队/家庭共用一台)
- ✅ 安卓 + 去谷歌环境 / 内网设备,不想让消息经过任何云
- ✅ 用 Claude Code / Codex,想要一个权限被锁死只读不了历史的"任务完成"通知口(内置 MCP 很香)
- ✅ 树莓派 / NAS 上跑告警:镜像多架构齐、单目录备份
- ❌ iPhone 用户
- ❌ 需要附件、定时、按钮交互、topic 级 ACL 的场景(用 ntfy)
一句话总结
gotify 把"自建推送"做成了一个正经的自托管应用:应用发、客户端收、用户管,REST 进 WebSocket 出,MIT、单二进制、多架构镜像。3.x 内置的 /mcp 端点用一把只能发消息的 token 把 agent 通知口做得很克制——这是 2026 年我看它最顺眼的地方。
想要更"协议化"、带 iOS 客户端、附件、定时和 topic 级 ACL 的方案,看同批更新的 ntfy。