这是「Docker 好项目」系列的第 13 期。前面几期里,Uptime Kuma 说「服务挂了要告诉你」、changedetection.io 说「网页变了要告诉你」——但「告诉」这两个字落到哪个通道,一直悬着。这一期把这条通道自己搭起来:ntfy。

痛点开场
自托管玩到一定数量,你会发现一个问题:告警发不出去。
Uptime Kuma 监控到站点掉线,通知栏里一红;changedetection.io 抓到商品降价,页面上多一条记录;Gitea 有人提了 issue,你三天后才看到;半夜数据同步脚本挂了,第二天早上才发现——因为你根本没收到通知。
这时候有两条路:
一条是接第三方推送。Bark、Server 酱、Telegram Bot、企业微信机器人……每个都能用,但每个都有自己的脾气:要么要注册要实名、要么限速限条数、要么消息内容被人读、要么哪天免费额度没了就断。最要命的是每接一个新服务,你就要学一套新的 API。
另一条是给自己搭一条推送通道:一个 HTTP 接口,POST 一行字,手机上就响。 这件事 ntfy 干得比谁都干净。
ntfy(读作 "notify")的核心就一句话:PUT/POST 到一个 URL,等于发一条推送。 没有 SDK、没有账号体系、没有 App 强绑定——curl 就是它的客户端。它的作者 Philipp Heckel 维护这个项目很多年,代码质量在自托管圈子里口碑很硬。
能力边界
能干什么
- HTTP 发布/订阅:
curl -d "你好" https://你的域名/主题就是一次推送,任何能发 HTTP 请求的东西都能接入(脚本、CI、路由器、老旧设备) - 多种订阅方式:SSE、WebSocket、JSON 流、Raw 流,浏览器/命令行/手机都能收
- 官方客户端齐全:Android、iOS、Web(PWA),也能被 UnifiedPush 生态直接当作推送通道
- 富消息:标题、优先级(1–5)、标签 emoji、点击跳转、Markdown 正文、定时延迟发送、操作按钮(点按钮直接回发一个 HTTP 请求,等于「手机上的确认键」)
- 附件:直接 PUT 一个文件上去,手机能看图
- 多用户 + 细粒度 ACL,可以按主题(支持通配符)授权读/写
- Web Push(浏览器后台推送)、邮件转发(
X-Email头)、Twilio 语音电话(X-Call头) - 内置 Prometheus 指标,方便接进监控
不干什么
- 不替你做「监控判断」——它只是通道,判断谁该告警是上游的事(Uptime Kuma 干)
- 不做消息归档/长期存储:默认只缓存 12 小时,过点就删
- 不做聊天,不回消息,没有会话概念
- 不做用户体系的自助运营:默认连注册入口都是关的,用户靠 CLI 或声明式配置创建
- 不是「微信推送」——它推的是自有 App 和浏览器,推不进微信
一句话:ntfy 是一根从服务器通到你手机的管子,管子里面流什么它不管。
部署前准备
- 一台能跑 Docker 的机器(主人的华为云 ECS 上再加一个 ntfy 容器毫无压力,它是 Go 单二进制 + SQLite,平时几十兆内存)
- 规划一个域名,比如
ntfy.你的域名.com(附件、iOS 推送、Web Push 都要求base-url正确,所以这一步别跳) - 华为云安全组放行反代用的 80/443(内网映射的 8080 端口不用对公网开)
- 两个宿主机目录:一个放缓存(消息库/附件),一个放配置(
server.yml) - 镜像:
binwiederhier/ntfy:v2.28
关于镜像 tag,这一期情况和上几期不一样,值得说清楚:
我实测了 binwiederhier/ntfy 的四个 tag——v2、v2.28、v2.28.0、latest,四个 tag 的 manifest digest 完全一致,说明它是「主版本 / 次版本 tag 跟着补丁一起滚动」的那种(跟第 10 期的 Gitea 同类)。所以这次可以放心用滚动次版本 tag :v2.28,出补丁自动跟上,大版本升级时你才会被拦一下。
但有两个坑必须注意:
- tag 前缀的
v不能丢。 我实测binwiederhier/ntfy:2.28(不带 v)返回 404,2.28.0也是 404。写:v2.28才有。 - ntfy 的 tag 判定来自仓库
.goreleaser.yml里的docker_manifests,它只生成latest/{{.Tag}}/v{{.Major}}/v{{.Major}}.{{.Minor}}这四类。
docker run 一行版
先手动跑一遍验证,正式用建议走下面的 compose:
mkdir -p /opt/ntfy/cache /opt/ntfy/etc
docker run -d \
--name ntfy \
-p 127.0.0.1:8080:80 \
-v /opt/ntfy/cache:/var/cache/ntfy \
-v /opt/ntfy/etc:/etc/ntfy \
-e TZ=Asia/Shanghai \
-e NTFY_BASE_URL=https://ntfy.你的域名.com \
-e NTFY_CACHE_FILE=/var/cache/ntfy/cache.db \
--restart unless-stopped \
binwiederhier/ntfy:v2.28 serve
三个要点:
- 最后那个
serve不能省。镜像的ENTRYPOINT是ntfy,serve是子命令,写全了才是ntfy serve。忘写会跑出 CLI 帮助信息然后退出。 - 容器里监听的是 80 端口(Dockerfile 里
EXPOSE 80/tcp,服务端默认listen-http: ":80"),所以映射是宿主机:80,不是宿主机:8080。我这里映射成127.0.0.1:8080(只绑本机),是给后面的反向代理用的——不建议直接把 80 裸奔到公网。 - 缓存文件路径要显式给
NTFY_CACHE_FILE。不设的话 ntfy 用纯内存缓存,容器一重启,所有待收消息就没了,since=续传也失效。
docker-compose 推荐版
services:
ntfy:
image: binwiederhier/ntfy:v2.28
container_name: ntfy
command: serve
restart: unless-stopped
ports:
# 只绑本机,由反向代理对外;不要图省事写成 "80:80"
- "127.0.0.1:8080:80"
volumes:
- ./data/ntfy/cache:/var/cache/ntfy # 消息库 + 附件
- ./data/ntfy/etc:/etc/ntfy # server.yml + templates
environment:
- TZ=Asia/Shanghai
- NTFY_BASE_URL=https://ntfy.你的域名.com
- NTFY_LISTEN_HTTP=:80
- NTFY_CACHE_FILE=/var/cache/ntfy/cache.db
- NTFY_CACHE_DURATION=12h
- NTFY_AUTH_FILE=/var/cache/ntfy/user.db
# 走反向代理,让限流按真实访客 IP 算(不设的话所有人共用一个桶)
- NTFY_BEHIND_PROXY=true
- NTFY_PROXY_FORWARDED_HEADER=X-Forwarded-For
# 附件功能:需要同时有 base-url 和 attachment-cache-dir
- NTFY_ATTACHMENT_CACHE_DIR=/var/cache/ntfy/attachments
- NTFY_ATTACHMENT_FILE_SIZE_LIMIT=15M
- NTFY_ATTACHMENT_EXPIRY_DURATION=3h
# iOS 自建服务器要收及时推送,必须告诉它去哪个上游「敲一下」
- NTFY_UPSTREAM_BASE_URL=https://ntfy.sh
- NTFY_LOG_LEVEL=info
healthcheck:
test: ["CMD-SHELL", "wget -q --tries=1 http://localhost:80/v1/health -O - | grep -Eo '\"healthy\"\\s*:\\s*true' || exit 1"]
interval: 60s
timeout: 10s
retries: 3
start_period: 30s
几个「为什么这么写」:
NTFY_BASE_URL不是可选项。附件下载链接、邮件里的主题地址、iOS 的 poll 主题、Web Push 全都从它推出来。写错会得到一堆指向 localhost 的链接。NTFY_BEHIND_PROXY=true配合NTFY_PROXY_FORWARDED_HEADER:不加这个,ntfy 会把反代的 IP 当成所有访客的 IP,于是全局共用一个限流桶——你自己多刷两下就被 429。- 健康检查用的是镜像自带的 busybox
wget(基础镜像是 alpine),抓/v1/health然后断言"healthy":true,跟 1Panel 应用商店里的写法一致。 NTFY_UPSTREAM_BASE_URL是给 iOS 用的。Android 走 WebSocket 直连就行,iOS 因为系统限制必须靠 APNS,所以要让ntfy.sh帮忙发一个「去看看」的空消息,真内容还是从你自己服务器拉的。不设这个,iOS 上要么收不到,要么延迟几分钟。
配置项逐项解释
下面这张表的默认值来自源码 server/config.go(v2.28.0 实测),环境变量一律带 NTFY_ 前缀(- 换成 _):
| 变量 | 默认值 | 说明 / 为什么这么写 |
|---|---|---|
NTFY_BASE_URL |
空 | 对外可访问的地址,必须填。不填 = 附件没链接、iOS 推送不工作、Web Push 报错 |
NTFY_LISTEN_HTTP |
:80 |
容器内监听地址。镜像里就是这个容器端口,映射时别搞反 |
NTFY_CACHE_FILE |
空 | 空 = 纯内存缓存。生产一定要设,否则重启丢消息、since= 失效 |
NTFY_CACHE_DURATION |
12h |
消息保留时长。设 0 等于彻底关缓存(省磁盘,但没法和 since= 配合) |
NTFY_AUTH_FILE |
空 | 空 = 完全没有访问控制,任何人可读可写任何主题。设了才启用鉴权和 ACL |
NTFY_AUTH_DEFAULT_ACCESS |
read-write |
未命中的访问默认权限。⚠️ 注意:默认是 read-write,不是 deny-all。要锁死必须显式改 |
NTFY_BEHIND_PROXY |
false |
反代后面必须设 true,否则限流按一个 IP 算 |
NTFY_PROXY_FORWARDED_HEADER |
X-Forwarded-For |
真实 IP 从哪个头读。别把它设成空字符串——设了 behind-proxy 又留空,ntfy 启动直接报错退出 |
NTFY_ATTACHMENT_CACHE_DIR |
空 | 附件目录,开了才能上传文件,s3://... 可接对象存储。必须同时有 base-url |
NTFY_ATTACHMENT_FILE_SIZE_LIMIT |
15M |
单文件上限 |
NTFY_ATTACHMENT_TOTAL_SIZE_LIMIT |
5G |
附件目录总容量上限 |
NTFY_ATTACHMENT_EXPIRY_DURATION |
3h |
附件过期清理时间。别当图床用 |
NTFY_UPSTREAM_BASE_URL |
空 | 自建服务器 + iOS 客户端时必须设 https://ntfy.sh |
NTFY_MESSAGE_SIZE_LIMIT |
4K |
消息体上限。建议保持 4K:FCM/APNS 本身就在这个量级,调大反而让手机端推送不稳 |
NTFY_KEEPALIVE_INTERVAL |
45s |
保活心跳间隔,防中间设备掐长连接。Android App 有 77s 硬编码超时,所以别调大 |
NTFY_GLOBAL_TOPIC_LIMIT |
15000 |
主题总数上限,个人用根本碰不到 |
NTFY_VISITOR_REQUEST_LIMIT_BURST |
60 |
每访客请求桶容量;REPLENISH 默认 5s 补一个 |
NTFY_VISITOR_SUBSCRIPTION_LIMIT |
30 |
每个访客的并发订阅(长连接)数 |
NTFY_VISITOR_EMAIL_LIMIT_BURST |
16 |
邮件转发的每访客配额,REPLENISH 默认 1h |
NTFY_ENABLE_SIGNUP |
false |
Web UI 注册入口默认关闭,保持关闭是好事 |
NTFY_ENABLE_LOGIN |
false |
Web UI 登录入口默认关闭。自己用的话用 token 就够了,不一定要开 |
NTFY_REQUIRE_LOGIN |
false |
设 true 后 Web 应用必须登录才能看。对公网暴露时建议开 |
NTFY_ENABLE_METRICS |
false |
开 /metrics(Prometheus 格式)。开了记得在反代那里挡住这个路径 |
NTFY_WEB_ROOT |
/ |
Web 应用挂载路径,disable 可完全关掉 Web UI |
NTFY_LOG_LEVEL |
info |
支持 trace/debug/info/warn/error,排障时临时调 debug |
NTFY_DATABASE_URL |
空 | v2.28 起支持用 PostgreSQL 存全部数据。注意:设了它就不能再设 cache-file / auth-file / web-push-file,而且会隐式打开鉴权 |
1Panel 面板怎么搞
1Panel 应用商店里有 ntfy 官方应用(当前版本 2.28.0),路径是 应用商店 → 搜索 ntfy → 安装。它的默认值如下:
| 项 | 默认值 |
|---|---|
| 镜像 | binwiederhier/ntfy:v2.28.0 |
宿主端口(PANEL_APP_PORT_HTTP) |
40265 |
| 容器内部端口 | 80 |
| 时区 | Asia/Shanghai |
| PUID / PGID | 1000 / 1000 |
| 缓存挂载 | ./data/cache/ntfy → /var/cache/ntfy |
| 配置挂载 | ./data/ntfy → /etc/ntfy |
这里有个必须知道的落差:商店表单里只有端口、时区、PUID/PGID 四项,没有 base-url、没有 auth-file、没有附件开关。所以装完之后:
- 打开 1Panel 的 容器 → 编排(或应用目录),进到
./data/ntfy/目录 - 新建/编辑
server.yml,把要用的配置写进去(下节给了一份可直接抄的) - 回到容器页 重启 ntfy
因为容器挂载了 /etc/ntfy,而 ntfy 默认就从这个路径读 server.yml,改完重启即生效,不用重建容器。
实操提示:1Panel 的 ntfy 应用把
user设成了1000:1000(非 root)。如果你手工改过挂载目录,记得让宿主机目录属于 1000 用户,否则启动会报无权限写cache.db:bash chown -R 1000:1000 /opt/1panel/apps/ntfy/ntfy/data
更推荐的做法:既然这台华为云 ECS 已经在跑 1Panel,用 容器 → 编排 直接贴本文上面那份 compose 更省事——参数一次写全,NTFY_BASE_URL、NTFY_BEHIND_PROXY、附件、健康检查都在,比装完商店应用再补配置文件清爽。
首次访问
- 浏览器打开
http://<你的IP>:8080(或反代配好后的域名),能看到 ntfy 的 Web 应用就是通了 - 健康检查先确认一下:
curl -s http://127.0.0.1:8080/v1/health
# {"healthy":true}
- 别急着发消息。默认状态下 ntfy 是「谁都能读谁都能写」的,先按下一节把鉴权补上
- 手机装官方 App(Android 在 F-Droid / Google Play,iOS 在 App Store,也可以用 PWA),在 App 里「添加订阅」,服务器地址填你的域名,主题名填你自己起的
- 验证推送:
curl -d "服务器通了 ✅" https://ntfy.你的域名.com/我的主题
手机上应该立刻弹通知。
手机 App 的界面大概长这样(官方截图):

最小可用配置
如果只想先跑通、链路通了再加固,这份 server.yml 是最小集(写到 /opt/ntfy/etc/server.yml,或 1Panel 的 ./data/ntfy/server.yml):
# 对外地址(必填,附件/iOS/WebPush 都依赖它)
base-url: "https://ntfy.你的域名.com"
# 消息落盘,重启不丢
cache-file: "/var/cache/ntfy/cache.db"
cache-duration: "12h"
# 走反向代理
behind-proxy: true
proxy-forwarded-header: "X-Forwarded-For"
# iOS 及时推送
upstream-base-url: "https://ntfy.sh"
改完重启容器即可。这份配置里故意没开鉴权,是为了让你先确认链路通;确认之后,下一步马上做加固。
加固:把「谁都能发」改成「只有我能发」
按顺序执行,别调换:
# 1) 创建管理员(密码走环境变量传进去,避免明文进 shell history)
docker exec -e NTFY_PASSWORD='换成你的强密码' -it ntfy ntfy user add --role=admin admin
# 2) 生成一个访问令牌给脚本用(复制输出的 tk_ 开头的串)
docker exec -it ntfy ntfy token add --label "告警脚本" admin
然后在 server.yml 里加两行、重启:
auth-file: "/var/cache/ntfy/user.db"
auth-default-access: "deny-all" # ← 关键:默认全拒
重启后:
# 匿名发布应该被拒(401/403)
curl -i -d "测试" https://ntfy.你的域名.com/我的主题
# 带 token 才能发
curl -d "只有我能发 ✅" -H "Authorization: Bearer tk_你的令牌" \
https://ntfy.你的域名.com/我的主题
几点说明:
admin角色在 ntfy 里绕过 ACL(源码里管理员直接放行),所以不用给 admin 单独授权主题。普通用户才需要ntfy access <用户> <主题通配符> rw|ro|wo逐条授权。- 授权命令形如:
docker exec -it ntfy ntfy access 老婆 "家庭*" ro - 如果不想用 CLI,ntfy 支持声明式创建用户/权限/令牌,环境变量
NTFY_AUTH_USERS、NTFY_AUTH_ACCESS、NTFY_AUTH_TOKENS每次启动自动落库,格式分别是用户名:密码哈希:角色、用户名:主题通配:权限、用户名:令牌:标签。密码哈希用docker exec -it ntfy ntfy user hash生成。 - 用户名密码也能用 HTTP Basic:
curl -u admin:密码 ...。另外在没法设请求头的场景(比如某些只能填 URL 的设备)可以用查询参数:?auth=base64(整个 Basic 头),也就是把Basic xxx再 base64 一次。
告警 / 通知配置
ntfy 自己是「通道」,所以这一节分两块:怎么让别的服务推到 ntfy,以及怎么监控 ntfy 自己。
1. 上游服务 → ntfy
- Uptime Kuma(第 1 期):设置 → 通知 → 新增 → 类型选 ntfy(原生支持,不是 webhook 绕)。服务器 URL 填
https://ntfy.你的域名.com,主题填你的主题,鉴权方式可选「用户名密码」或「访问令牌」,Kuma 会自动用 Basic / Bearer 头去发。还能顺带填X-Call走电话告警。 - changedetection.io(第 9 期):通知 URL 用 Apprise 的 ntfy 协议:
- 自建 + HTTPS:
ntfys://ntfy.你的域名.com/我的主题 - 自建 + HTTP:
ntfy://ntfy.你的域名.com:8080/我的主题 - 要带令牌:
ntfys://tk_你的令牌@ntfy.你的域名.com/我的主题?auth=token - 任何脚本:一行就够,放在脚本末尾最省心。
#!/usr/bin/env bash
set -euo pipefail
TOPIC="https://ntfy.你的域名.com/我的主题"
TOKEN="tk_你的令牌"
if ./sync-job.sh; then
curl -s -d "同步完成 ✅ $(date '+%F %H:%M')" -H "Authorization: Bearer $TOKEN" -H "X-Tags: white_check_mark" "$TOPIC"
else
curl -s -d "同步失败 ❌ 退出码 $?" -H "Authorization: Bearer $TOKEN" -H "X-Priority: high" -H "X-Tags: rotating_light" "$TOPIC"
fi
2. ntfy 富消息速查
| 想要的效果 | 怎么写 |
|---|---|
| 标题 | -H "X-Title: 磁盘告警" 或 ?title=磁盘告警 |
| 优先级 | -H "X-Priority: high"(可用 5/max/urgent、4/high、3/default、2/low、1/min,也可直接写数字 1–5) |
| emoji 标签 | -H "X-Tags: warning,skull"(用 emoji shortcode,不用贴 emoji 字符) |
| 点击跳转 | -H "X-Click: https://你的监控面板" |
| Markdown 正文 | -H "X-Markdown: yes" |
| 定时发送 | -H "X-Delay: 30m" |
| 附件 | curl -T 报表.pdf -H "Filename: 报表.pdf" -H "Message: 今日报表" ... |
| 操作按钮 | -H "X-Actions: view, 打开面板, https://...; http, 重启服务, https://.../restart, method=POST" |
| 同时发邮件 | -H "X-Email: 你的邮箱@example.com"(需配 smtp-sender-*) |
3. 监控 ntfy 自己
ntfy 挂了你就什么都收不到了——这是所有「通知通道」的经典盲区。两个办法:
- 用 Uptime Kuma 加一个 HTTP 监控,URL
https://ntfy.你的域名.com/v1/health,关键字填"healthy":true,并且把告警通知配到第二个独立渠道(比如邮件或另一台机器上的 ntfy)。只配 ntfy 自己等于没配。 - 想接 Prometheus:
enable-metrics: true后暴露/metrics。记得在反代里把/metrics路径挡住或加 IP 白名单,指标里有主题数量之类的信息。
反向代理与 HTTPS
ntfy 自己不处理 TLS,交给反代。以 Nginx Proxy Manager(第 2 期)为例:
- Hostname/IP:
127.0.0.1:8080(对上 compose 里绑的本机端口) - Scheme:
http - 勾上 SSL,申请 Let's Encrypt 证书
- 不要在 NPM 里改路径重写,ntfy 所有功能都挂在根路径上,会直接坏掉
Caddy 用户一份 Caddyfile 就够:
ntfy.你的域名.com {
reverse_proxy 127.0.0.1:8080
}
三个反代相关的注意点:
base-url必须和公网地址一字不差(协议 + 域名),否则附件链接指向内网、iOS 收不到推送behind-proxy: true一定要开,否则所有人共用一个限流桶- 走 Cloudflare 的话,确认
X-Forwarded-For能透传到源站;ntfy 的 45s 心跳(keepalive-interval)本来就是为「中间设备掐长连接」准备的,正常能看到消息持续到达。如果发现通知延迟异常,先把这个子域名切到 DNS only(灰云)对比一下,能立刻定位是不是 CDN 层的问题
踩坑清单
- tag 没带
v拉不到:binwiederhier/ntfy:2.28实测 404,必须写:v2.28(或:v2.28.0/:v2)。这是本期最容易犯的错。 - 忘了
serve子命令:ENTRYPOINT是ntfy,命令行得写ntfy serve。compose 里就是command: serve。 - 端口映射搞反:容器内是 80,不是 8080。写成
8080:8080会连不上。 cache-file不设 = 重启丢消息:默认纯内存缓存,容器一重启,since=续传和离线消息全没。- 默认是「谁都能发」:
auth-file不设就没鉴权;就算设了auth-file,auth-default-access默认也是read-write。想锁死必须显式写deny-all。任何对公网开放的 ntfy,第一件事就是加固。 behind-proxy单开着没事,但proxy-forwarded-header别设成空:源码里有硬校验「设了 behind-proxy 就必须有 forwarded header」,留空会让 ntfy 启动直接失败退出。默认值X-Forwarded-For保持不动就行。message-size-limit别乱调大:默认 4K 是配合 FCM/APNS 的,调到几百 K 换来的是手机端推送不稳定。- 附件要两个条件同时满足:
attachment-cache-dir+base-url。少一个,上传会报错或者下不下来。 - iOS 收不到及时推送:自建服务器必须设
upstream-base-url: "https://ntfy.sh"。Android 用户如果想要省电的后台推送,还得配firebase-key-file(要自己申请 FCM 凭证),不想折腾就用「保持前台服务」模式,代价是费电。 - 非 root 运行要改目录属主:镜像 Dockerfile 里没有
USER指令,默认是 root;但官方 compose 和 1Panel 应用都用user: UID:GID(1000:1000)跑。改成非 root 后,宿主机挂载目录必须先chown,否则写不了cache.db。 database-url与三个文件互斥:想用 PostgreSQL 存数据,就不能再设cache-file/auth-file/web-push-file,而且它会隐式开启鉴权,别以为不设 auth 相关项就还是开放的。
备份
ntfy 要备份的东西很少,就三样,都在挂载目录里:
| 文件 | 内容 | 重要性 |
|---|---|---|
cache.db |
消息缓存(默认只留 12h) | 低——丢了只是丢最近 12 小时消息 |
user.db |
用户、ACL、访问令牌 | 高——丢了要重建所有账号和令牌 |
server.yml |
全部服务端配置 | 高 |
一句话备份整个目录:
# 先停容器再拷,避免拷到写了一半的 SQLite
docker stop ntfy
tar czf ntfy-backup-$(date +%F).tar.gz -C /opt/ntfy cache etc
docker start ntfy
只想备份账号和配置(最该备份的):
mkdir -p ~/ntfy-backup-$(date +%F)
docker stop ntfy
cp /opt/ntfy/cache/user.db /opt/ntfy/etc/server.yml ~/ntfy-backup-$(date +%F)/
docker start ntfy
恢复就是把文件放回去、重启容器。提示:趁早备份 user.db——令牌是明文存在里面的,丢了就只能重新生成、重新填回所有上游服务,很烦。
小结
适合谁
- 自托管一套东西(监控 + 网页监测 + Git + 媒体库),需要一条自己的告警通道,不想被第三方限速和审查
- 会写 shell/Python 脚本,想给「跑完/跑挂」加一条手机通知的人
- 在跑 Uptime Kuma 或 changedetection.io,正在纠结「通知发去哪」的人(这两个都能直接接 ntfy)
不适合谁
- 只想「在微信里收到提醒」的——ntfy 推不进微信,那是另一条路(企业微信机器人)
- 想要消息永久留档、当 IM 用的——ntfy 只缓存 12 小时,不做聊天
- 完全不想碰命令行、只想要「装完就能用」的——鉴权加固必须进一次终端(不过也就三步)
把这台华为云 ECS 上的 ntfy 搭起来,前面十几期介绍的那些服务就都有了统一的「出口」。告警这条链路,值得自己握在手里。
项目地址
- GitHub:https://github.com/binwiederhier/ntfy
- 官网 / 文档:https://ntfy.sh(文档全在这里,配置生成器在
/docs/config/) - 客户端下载:Android / iOS / Web 都在官网首页
- Docker 镜像:
binwiederhier/ntfy:v2.28(Docker Hub;国内拉取慢可以走镜像加速,1Panel 应用商店里也预置了这个镜像)