Gotify 适合放在个人服务器、小团队内部工具和自建监控体系里,承担“把机器状态及时送到安卓手机”的职责。它不应该被包装成平台级原生推送替代品,也不应该被当成关键生产事故的唯一告警链路。更准确的定位是:一台由你自己控制的消息中转服务器,通过 REST API 接收应用、脚本和监控系统的通知,再通过 WebSocket 把消息交给 Web UI、桌面浏览器或 Android 客户端。
这个定位决定了部署方式。Gotify 的安装本身很简单,真正需要认真设计的是账户、令牌、反向代理、数据持久化、备份恢复、安卓保活、通知优先级、失败告警和验收标准。只要其中一个环节靠猜,最后都会变成“看起来能推送,真正出事时不知道为什么没响”。下面按生产部署的口径给出一套可执行方案,适合把 Gotify 放到 VPS、轻量云、家庭服务器公网入口或内网运维面板旁边。
先把架构说清楚:Gotify 不是移动厂商推送
Gotify 官方 server 当前稳定版本为 v3.1.1,Android 客户端当前稳定版本为 v2.10.1。服务端提供 Web UI、REST API、WebSocket、用户管理、Application、Client、插件机制和消息存储;Android 客户端连接 gotify/server,收到新消息后在系统通知栏展示。这个组合足够覆盖自建监控、备份脚本、定时任务、内部服务发布通知和个人自动化提醒。
但 Gotify 的 Android 通知依赖客户端与服务器之间的长期连接。它不是 FCM、APNs 或手机厂商通道,不具备系统级唤醒能力。Android 如果因为省电策略杀掉 Gotify,或者网络把后台连接断掉,手机就可能收不到即时通知。官方 Android README 也明确提示:默认电池优化可能杀死长时间运行的应用,启用电池优化时可能无法收到通知。因此,生产部署时必须把“安卓端保活和前台连接限制”写进验收,不要向用户承诺“App 被杀也一定能推送”。
一个稳妥的生产结构通常是:
- Gotify Server 只监听本机或内网端口,例如容器内 80、宿主机 127.0.0.1:8085。
- Caddy、Nginx、Traefik 或 Cloudflare Tunnel 负责 HTTPS、证书续期、访问日志和 WebSocket 转发。
- SQLite 数据库、应用图标、上传图片和插件目录持久化到
/app/data。 - 监控系统、cron、备份脚本、CI/CD、NAS、路由器或业务服务使用 Application Token 调用
/message。 - Android、Web UI 或其它读取端使用 Client Token 或登录会话接收、查看和管理消息。
- 另有一条外部告警链路监控 Gotify 本身,避免“通知系统坏了,却没人通知”。
Application Token 和 Client Access 必须分开理解
Gotify 最常见的安全误用,是把“能发消息”和“能读消息、管应用”混为一个令牌。服务端模型里,Application 代表一个发送方,例如 uptime-kuma、backup-job、ssl-renewal、production-api。每个 Application 都有自己的 token,可以用于向 /message 发送通知。这个 token 应该只放在对应系统里,并且按来源拆分,方便撤销、追踪和限权。
Client 则代表一个接收和管理消息的客户端,例如 Android 手机、浏览器会话、桌面脚本或内部看板。Client Token 能访问更多用户维度的信息,不应塞进 cron 脚本、公开仓库、前端页面或第三方监控 Webhook。管理员登录密码更不应该出现在自动化脚本里。生产环境的基本规则是:发消息用 Application Token;读消息、管理应用和创建新令牌用登录或 Client Token;不同系统不要共用一个 Application。
建议上线前建立一张令牌台账:名称、用途、保存位置、负责人、默认优先级、是否允许公网来源、最后使用时间、撤销方式。Uptime Kuma 一个应用,备份任务一个应用,证书任务一个应用,生产 API 一个应用。这样某个脚本泄露 token 时,只需要撤销一个发送方,而不是重置整个通知系统。
Compose 部署:先保证数据不会随容器消失
Gotify 可以直接用 Docker 部署。生产环境建议固定主版本镜像,不要使用无边界的 latest 自动滚动。以下示例以官方当前 server v3.1.1 为基线,使用 SQLite 和宿主机目录持久化,适合单机、小团队和个人运维场景:
mkdir -p /opt/gotify/data
cd /opt/gotify
cat > docker-compose.yml <<'YAML'
services:
gotify:
image: gotify/server:3.1.1
container_name: gotify
restart: unless-stopped
user: "1000:1000"
ports:
- "127.0.0.1:8085:80"
environment:
TZ: Asia/Shanghai
GOTIFY_SERVER_PORT: 80
GOTIFY_DEFAULTUSER_NAME: admin
GOTIFY_DEFAULTUSER_PASS: change-this-before-first-login
GOTIFY_REGISTRATION: "false"
GOTIFY_SERVER_STREAM_ALLOWEDORIGINS: "https://push.example.com"
GOTIFY_SERVER_SECURECOOKIE: "true"
volumes:
- ./data:/app/data
YAML
docker compose up -d
这里有几个细节比命令本身更重要。第一,./data:/app/data 是底线,不能删。Gotify 默认 SQLite 数据库、上传图片、插件目录和证书缓存都在数据目录附近;如果没有持久化,容器重建可能带走用户、应用、消息和令牌。第二,宿主机只绑定 127.0.0.1:8085,不把容器端口直接暴露到公网。第三,初始密码只用于第一次登录,登录后必须在 Web UI 里改掉,并把 Compose 文件里的默认密码视为引导配置,而不是长期凭据。第四,关闭公开注册,除非你明确要让用户自助创建账号。
如果需要 PostgreSQL,也可以通过配置环境变量切换数据库。但对个人和小团队来说,SQLite 加可靠备份通常更简单。不要为了“看起来更生产”而引入自己不会维护的数据库。Gotify 的关键数据量一般不大,真正的可用性瓶颈通常在反向代理、证书、手机连接和告警链路,而不是 SQLite。
TLS 和反向代理:WebSocket 转发必须验收
Gotify 可以自己处理 TLS,也可以放在反向代理后面。生产上更推荐由 Caddy、Nginx 或 Traefik 统一处理证书和访问入口。无论用哪一种,必须确保 WebSocket 能通过代理转发,否则 Web UI 或 Android 客户端可能登录正常但实时消息断开。
Caddy 示例:
push.example.com {
encode zstd gzip
reverse_proxy 127.0.0.1:8085
header {
X-Content-Type-Options nosniff
Referrer-Policy no-referrer
}
}
Caddy 默认对 WebSocket 支持较好,通常不需要额外写 Upgrade 头。Nginx 则建议明确写出升级配置:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 443 ssl http2;
server_name push.example.com;
location / {
proxy_pass http://127.0.0.1:8085;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
验收时不要只打开首页。至少要完成四个动作:浏览器访问 https://push.example.com 并登录;创建 Application;用 curl 发一条消息;打开 Android 客户端或 Web UI 等待实时出现。若页面能登录但消息必须刷新才出现,优先检查 WebSocket、反向代理超时、Cloudflare 代理层和 GOTIFY_SERVER_STREAM_ALLOWEDORIGINS。
初始账号、注册与最小公网暴露
Gotify 默认配置中的初始账号密码是 admin/admin。这个事实必须进入上线清单,因为许多自建服务事故都不是复杂漏洞,而是默认口令暴露。第一次启动后应立即登录修改密码,确认注册关闭,创建真实的管理员账号或至少改掉默认用户密码,然后再开放公网域名。
最小暴露原则可以按下面执行:
- 公网只开放 443;80 只用于 ACME/跳转;Gotify 容器端口只监听本机。
- 管理入口使用强密码,最好放在 VPN、Tailscale、Cloudflare Access、Zero Trust 或 IP 白名单后面。
- Application Token 不写进 URL 收藏夹和公开文档;调用时优先使用
X-Gotify-Key请求头,减少代理日志泄露风险。 - 日志系统不要记录完整 token。若必须排查请求,先做脱敏。
- 不要把 Gotify 当公开留言接口。任何能调用
/message的人都能制造通知噪声,严重时会淹没真正事故。
Gotify 支持用户、客户端和应用管理,也支持插件。但越多功能暴露到公网,越需要有升级和审计习惯。个人部署可以保持极简:一个管理员、若干 Application、Android 客户端、少量脚本。等稳定后再考虑 OIDC、插件和多用户管理。
发送消息:curl 示例和优先级策略
Gotify 的核心接口很直接。创建 Application 后拿到 token,脚本里发送:
curl -sS -X POST "https://push.example.com/message" \
-H "X-Gotify-Key: ${GOTIFY_APP_TOKEN}" \
-F "title=备份完成" \
-F "message=web-01 备份已写入对象存储,快照编号 2026-09-22-0300" \
-F "priority=5"
也可以使用 JSON,便于传递 extras:
curl -sS -X POST "https://push.example.com/message" \
-H "X-Gotify-Key: ${GOTIFY_APP_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"title":"SSL 证书即将过期","message":"api.example.com 证书剩余 9 天,请检查续期任务","priority":8}'
优先级不要随便全部设成 10。Android 客户端的 README 给出了大致行为:priority 0 不显示系统通知;1–3 显示通知栏图标;4–7 会有图标和声音;8–10 还会加入振动。不同 Android 版本、系统通知渠道和厂商设置会影响最终表现,但这个区间足以作为团队约定。建议:日常成功通知 1–3;需要人工查看但不紧急 4–5;会影响用户或数据安全的事故 8–10;高频日志不要进 Gotify,最多汇总后低优先级发送。
Uptime Kuma、cron、备份和证书过期:四个常用接入
Gotify 最适合接“已经有判断结果”的系统,而不是替代监控判断。Uptime Kuma 负责探测站点和服务,Gotify 负责把 Up/Down 结果送到手机。配置时选择 Gotify 通知类型,填入服务器地址和 Application Token,先发测试消息,再制造一个受控的监控失败,确认恢复通知也能收到。只测试“发送测试”不够,因为真实告警可能带不同标题、内容和优先级。
cron 任务可以用一个小封装避免每个脚本重复写 curl:
#!/usr/bin/env bash
set -euo pipefail
notify() {
local title="$1" message="$2" priority="${3:-4}"
curl -fsS -X POST "https://push.example.com/message" \
-H "X-Gotify-Key: ${GOTIFY_APP_TOKEN}" \
-F "title=${title}" \
-F "message=${message}" \
-F "priority=${priority}" >/dev/null
}
if /usr/local/bin/nightly-job; then
notify "定时任务完成" "nightly-job 成功,主机 $(hostname)" 2
else
code=$?
notify "定时任务失败" "nightly-job 退出码 ${code},请查看日志" 8
exit "$code"
fi
备份脚本不要只通知“完成”。更有价值的消息应包含备份对象、目标位置、快照编号、耗时、大小和校验结果。失败通知应带最后几行脱敏错误,避免手机上只看到“失败”两个字却无法判断是否需要半夜起床。
SSL 证书过期可以用 openssl 做最小检查:
domain=api.example.com
end=$(echo | openssl s_client -servername "$domain" -connect "$domain:443" 2>/dev/null \
| openssl x509 -noout -enddate | cut -d= -f2)
end_ts=$(date -d "$end" +%s)
now_ts=$(date +%s)
days=$(( (end_ts - now_ts) / 86400 ))
if [ "$days" -lt 14 ]; then
curl -fsS -X POST "https://push.example.com/message" \
-H "X-Gotify-Key: ${GOTIFY_APP_TOKEN}" \
-F "title=证书剩余 ${days} 天" \
-F "message=${domain} TLS 证书即将过期,请检查续期链路" \
-F "priority=8"
fi
macOS/BSD 的 date 参数不同,生产脚本应按运行系统调整。关键不是某段命令,而是把“证书续期失败”变成可被手机看到的事件。
监控通知通道本身:不要让 Gotify 成为单点盲区
如果所有监控都通过 Gotify 发出,而 Gotify 自己宕机、域名解析失败、证书过期、磁盘满或 Android 客户端断线,团队会进入最糟糕的状态:真正需要通知时,通知系统先失效。生产验收必须给 Gotify 本身再建一条外部通道。
最低要求包括:
- 外部 HTTP 监控检查
https://push.example.com/health或至少检查首页 200/302 与 TLS 可用性。 - 磁盘监控覆盖
/opt/gotify/data所在分区,避免 SQLite 写入失败。 - 反向代理证书过期监控不依赖 Gotify 自己发送,至少同时发邮件、短信、另一个聊天工具或云厂商告警。
- 每天或每周发送一条低优先级心跳消息,人工确认 Android 端仍能收到。
- 在 Gotify Web UI 或服务端日志里检查 Android Client 的最后使用时间,长期未更新说明连接可能不稳定。
更严格的做法是建立双通道:普通提醒走 Gotify,严重事故同时走短信、电话、邮件或企业 IM。Gotify 很适合个人和小团队的自建通知中心,但不应该成为唯一的生命线。
备份与恢复演练:复制 data 目录不等于完成
使用默认 SQLite 时,备份重点是 /opt/gotify/data。其中包含数据库、图片、插件和相关状态。建议在低峰期做文件级备份,或先暂停容器再打包,减少 SQLite 文件正在写入时被复制的风险。一个简单方案是:
cd /opt/gotify
docker compose stop gotify
tar -czf /var/backups/gotify/gotify-data-$(date +%F-%H%M).tar.gz data
docker compose start gotify
如果不能停机,可以考虑 SQLite 在线备份、文件系统快照或数据库迁移到外部 DB。但对大多数个人部署来说,定期短暂停机备份更容易理解,也更容易恢复。无论哪种方式,备份文件都应离机保存,至少放到另一台机器或对象存储;只存在同一块磁盘上,不能抵抗磁盘损坏和误删。
恢复演练应每季度至少做一次。找一台临时机器,安装相同 Compose 文件,解压 data 目录,启动 Gotify,完成以下验收:管理员能登录;Applications 和 Clients 仍在;历史消息能看到;curl 能用旧 Application Token 发消息;Android 或测试 Client 能收到新消息;插件如有启用也能加载。只有恢复演练通过,备份才算真实存在。
Android 端验收:把省电策略写进文档
Android 是 Gotify 部署里最容易被忽略的部分。服务端再稳定,手机端被系统杀掉也无法保证即时提醒。安装 Gotify Android 后,应完成下面的手机侧配置:
- 登录服务器并确认 WebSocket 连接状态正常。
- 关闭 Gotify 的电池优化,按机型参考 dontkillmyapp.com 处理后台限制。
- 允许通知权限,并检查通知渠道的声音、振动和重要性。
- 在 Android 8 及以上,如果前台连接通知太显眼,可以在系统通知设置里降低 Gotify foreground notification 的重要性,而不是直接禁止 Gotify 后台运行。
- 锁屏、息屏、切换网络、重启手机后分别发送测试消息。
验收结论要诚实:Gotify 能在应用保持连接时提供实时通知;省电策略、厂商后台管理、网络切换、用户手动杀进程都会影响送达。面向团队用户时,应在内部文档写清“若手机厂商严格杀后台,请同时保留邮件/短信/IM 告警”。这不是 Gotify 的缺陷,而是自建 WebSocket 通知与移动系统策略之间的边界。
常见失败模式与排查顺序
一、curl 返回 401 或 403。先检查 token 类型。Application Token 才适合发 /message;Client Token 和登录凭据不是给业务脚本随意使用的。再检查 token 是否被复制时多了空格、换行或引号。
二、Web UI 能打开但 Android 收不到。检查 Android 是否关闭电池优化,通知权限是否打开,客户端是否仍显示连接。再查反向代理 WebSocket Upgrade、代理超时、Cloudflare/网关是否中断长连接。
三、消息发送成功但没有声音。检查 priority 区间、Android 通知渠道、系统免打扰、厂商通知管理。Gotify 的 priority 只是输入信号,最终声音和振动仍受系统渠道控制。
四、升级后数据丢失。通常是没有持久化 /app/data,或新容器挂到了空目录。先停止写入,确认旧 data 目录是否还在,再决定回滚。不要在空库里重新创建一堆同名 Application 后继续运行,否则会让恢复更混乱。
五、备份通知成功但备份文件不可用。通知只能说明脚本走到了某一步,不能证明备份可恢复。必须把校验和、对象存储上传结果和定期恢复演练一起纳入消息内容或审计记录。
生产参数建议:少改默认值,但要知道默认值意味着什么
Gotify 的默认配置对本地试用很友好,但生产环境不能只靠“能启动”。默认数据库是 SQLite,默认连接文件在数据目录;默认用户是 admin,默认密码也是 admin;默认流式连接会定期 ping;默认注册关闭;默认消息可以存储在服务端供客户端查看。理解这些默认值,才能决定哪些要保留,哪些必须覆盖。
对单机生产部署,建议优先控制以下几类参数。第一是身份参数:GOTIFY_DEFAULTUSER_NAME 和 GOTIFY_DEFAULTUSER_PASS 只用于初始化,真正上线后要改成长期密码或切换到受控身份体系。第二是网络参数:容器内端口可以保持 80,但宿主机绑定应限制在本机,由反向代理统一接入公网。第三是流式连接来源:如果域名固定,可以设置 GOTIFY_SERVER_STREAM_ALLOWEDORIGINS,避免任意来源页面尝试建立流连接。第四是安全 Cookie:走 HTTPS 时开启 GOTIFY_SERVER_SECURECOOKIE 更符合预期。第五是日志等级:生产通常保留 info,排障时临时提高,不要长期把敏感请求细节打进日志。
还有一个容易被忽视的参数是 Application 的默认优先级。不要把所有应用都设成同一个值。备份成功、备份失败、证书预警、站点宕机、站点恢复、磁盘剩余空间不足,本来就不应该以相同强度打扰人。生产上应把默认优先级看成“这个来源的常态严重度”,再允许单条消息按事件覆盖。这样既能减少告警疲劳,也能让真正重要的通知更容易被听见。
升级策略:先读 release,再复制 data,再灰度验证
Gotify 服务端当前版本已经进入 v3.x,升级时要避免两个极端:一个是长期不升级,错过安全修复和客户端兼容改进;另一个是看到新镜像就自动拉取,半夜把通知系统滚坏。比较稳的做法是固定镜像标签,订阅官方 release,在维护窗口手动升级。
升级前先做三件事。第一,导出当前 Compose 文件、环境变量和反向代理配置,确认能回滚到旧版本。第二,备份 /opt/gotify/data,并记录备份文件的校验和。第三,在临时目录或测试机器用备份副本启动新版本,至少验证登录、应用列表、客户端列表、历史消息、curl 发消息和 Android 接收。确认通过后,再替换生产镜像标签并重启。
cd /opt/gotify
cp docker-compose.yml docker-compose.yml.$(date +%F-%H%M).bak
docker compose pull gotify
docker compose up -d
curl -fsS https://push.example.com/health
升级后不要只看容器状态。要发一条低优先级测试消息,再发一条高优先级测试消息,分别确认 Web UI 和 Android 端行为。还要检查反向代理日志中是否出现大量 101/200 以外的异常状态、Android 是否频繁重连、服务端日志是否有数据库迁移错误。若升级后实时消息异常,先回滚镜像,不要边生产边猜。
消息内容规范:手机通知要能直接指导下一步
很多 Gotify 部署失败不是技术失败,而是消息写得不可用。手机上弹出“任务失败”没有价值,值班者还要打开电脑、登录服务器、查脚本、翻日志。生产通知至少应该包含四类信息:对象、状态、影响和下一步。对象说明是哪台主机、哪个服务、哪个域名或哪个任务;状态说明成功、失败、降级还是恢复;影响说明是否影响用户、数据或备份窗口;下一步说明去哪看日志、是否需要立即处理。
例如“备份失败”不如“web-01 PostgreSQL 备份失败:对象存储上传返回 403,最近成功快照为 2026-09-21 03:00,请检查 access key”。“网站挂了”不如“api.example.com /health 连续 3 次 502,外部探测失败,Caddy 到 upstream 127.0.0.1:56001 可能不可达”。这种写法会让 Gotify 从“响一下”变成真正可执行的运维入口。
同样,恢复消息也很重要。只发 Down 不发 Up,会让人不知道事故是否结束;只发成功不发失败,会制造虚假的安全感。Uptime Kuma、cron 和备份脚本都应该成对设计:异常、持续异常、恢复、恢复后摘要。高频系统还需要节流和聚合,避免 100 条相同报警把手机通知栏刷爆。Gotify 不负责告警降噪,降噪应该在监控系统或脚本侧完成。
安全与隐私:通知内容本身也可能是敏感数据
Gotify 自托管给了你数据控制权,但不等于可以在通知里放任何内容。消息会存储在服务端,也会出现在手机通知栏、锁屏、Android 通知历史、浏览器页面和备份数据库里。如果通知里直接写完整邮箱、客户姓名、订单金额、服务器内网地址、数据库错误、访问令牌或下载链接,就要按敏感数据管理。
建议把通知正文分级。普通运行状态可以直接写;内部路径、主机名和错误摘要可以写但要避免密钥;用户数据、验证码、个人身份信息、完整 IP 列表和凭据不应进入 Gotify。需要排障时,可以在消息里给出内部日志系统的链接或工单编号,而不是把完整日志塞进通知。若业务涉及合规要求,还要明确 Gotify 数据保留周期,定期清理历史消息,并限制谁能登录 Web UI 查看历史。
反向代理访问日志也要处理 token 泄露问题。Gotify 支持通过请求头传递 X-Gotify-Key,比把 token 放在 URL 查询参数里更安全。URL 容易进入浏览器历史、代理日志、监控系统、错误页面和聊天记录。脚本示例里即使为了方便展示,也应优先使用请求头;团队文档更不能鼓励把 token 写成公开链接。
多用户与团队使用:少量共享可以,多租户不要硬撑
Gotify 支持用户管理,但它不是完整的企业告警平台。几个人共用一套实例没有问题:管理员创建应用,成员用各自客户端接收通知,必要时用不同用户隔离个人消息。问题在于,很多团队会把它越用越大,最后想让不同项目、不同客户、不同部门共享同一套 Gotify,并要求复杂审计、细粒度授权、轮班升级、确认闭环和报表。这时 Gotify 的简单性反而会变成边界。
如果确实要团队化使用,建议先定三条规则。第一,按项目或环境拆 Application,不允许“公共 token”到处复制。第二,管理员数量少而明确,普通成员只持有自己的客户端访问。第三,严重事故必须在更正式的值班系统里闭环,Gotify 只承担通知通道,不承担确认、升级和责任追踪。若团队已经需要 on-call 排班、升级策略、通知确认、自动降噪和审计报表,应尽早评估专门的告警平台,而不是在 Gotify 外面补一堆脆弱脚本。
一套可执行的首日上线流程
第一小时,准备域名、服务器、防火墙和反向代理。确认 443 可访问,容器端口不直接暴露公网,服务器时间同步正常。第二小时,部署 Compose,登录 Web UI,修改默认密码,关闭注册,创建至少三个 Application:uptime-kuma、backup、system-cron。第三小时,安装 Android 客户端,关闭电池优化,配置通知渠道,测试 0、3、5、8 四档优先级。
第四小时,把 Uptime Kuma、备份脚本和证书检查接入。每个接入都要做一次正向和反向测试:不仅要能发送测试消息,还要能触发真实失败和真实恢复。第五小时,做第一次备份和一次临时恢复演练,哪怕只是在同机另一个目录里恢复,也要确认旧 token 还能发消息。第六小时,配置外部监控,让另一个通道监控 Gotify 的 HTTPS、证书和磁盘。完成这六步后,Gotify 才算从“装好了”进入“可以依赖”的状态。
上线验收清单
| 项目 | 最低通过线 | 拒收条件 |
|---|---|---|
| 版本 | server 固定到 v3.1.1 或明确版本;Android 使用 v2.10.1 或明确版本 | 生产使用 latest 自动漂移且无回滚记录 |
| 数据 | /app/data 持久化,重建容器后应用、用户和消息仍在 | 容器删除后数据消失 |
| 入口 | HTTPS 可用,WebSocket 实时消息通过 | 只能刷新看到消息,实时连接失败 |
| 账号 | 默认密码已修改,注册关闭或有明确准入策略 | admin/admin 可登录公网实例 |
| 令牌 | Application 按系统拆分,token 不进公开仓库和前端 | 所有脚本共用管理员凭据或 Client Token |
| 通知 | 低、中、高优先级分别在 Android 上验证过声音/振动行为 | 只测试一条默认消息就上线 |
| 备份 | 离机备份和恢复演练完成 | 只有同盘压缩包,从未恢复 |
| 自监控 | Gotify 健康、证书、磁盘由外部通道监控 | Gotify 坏了只能靠 Gotify 通知 |
什么时候适合 Gotify,什么时候不适合
适合使用 Gotify 的场景很明确:你有自己的服务器或内网服务;通知对象主要是自己或少量运维成员;能接受自建系统需要维护;希望用 REST API 把各种脚本和监控串起来;对消息内容和数据存储位置有控制要求。家庭服务器、个人 VPS、独立开发者、小团队 SRE、实验环境和内部自动化都很适合。
不适合的场景也要直说:面向大量终端用户的商业 App 推送;要求 App 被杀后仍由系统级通道唤醒;强 SLA 的事故通知唯一链路;需要复杂多租户权限、审计合规和企业级值班排班;团队成员主要使用 iPhone 且没有其它通道。此时应该考虑 FCM/APNs、企业 IM、PagerDuty/Opsgenie、短信电话或云厂商告警,而不是让 Gotify 承担它本来没有承诺的能力。
Gotify 的价值在于简单、透明、可自托管。把它部署好以后,很多原本沉在日志里的结果会变成手机上的清晰事件:备份是否完成、站点是否掉线、证书是否快过期、定时任务是否失败、服务发布是否成功。只要你同时承认它的边界——WebSocket 连接、Android 后台限制、自建服务需要备份和自监控——它就是一套很实用的安卓自建通知基础设施。










