ntfy 自托管推送通知服务搭建:一条 curl 命令向手机发送通知

ntfy 自托管推送通知服务搭建:一条 curl 命令向手机发送通知

服务器跑完备份任务、定时脚本执行完毕、网站出现异常------这些事件如果能自动推送通知到手机,就不用守着终端盯日志了。实现这个需求的工具很多,但大多需要注册第三方账号、申请 API Key、配置 Webhook,流程繁琐。

ntfy 的设计思路完全不同:发送一条通知,只需要一行 curl 命令;接收通知,只需要在 App 里订阅一个 topic(主题)。没有注册流程,没有 SDK,没有复杂配置。自建服务器后,通知内容不经过任何第三方,适合推送包含敏感信息的业务告警。

本文介绍如何用 Docker Compose + Caddy 搭建 ntfy 私有推送通知服务。

服务器配置

ntfy 服务端资源消耗极低,和其他服务共享一台机器完全没问题。

项目 规格
CPU 1 核
内存 1GB
硬盘 10GB(消息持久化缓存)
系统 Ubuntu 22.04 / Debian 12

推荐使用雨云服务器 rainyun-com 的 1 核 1GB 机型来部署 ntfy,价格低廉,资源绰绰有余。注册填优惠码 2026off 领 5 折优惠券,新用户首单直接半价。

准备工作

确保服务器已安装 Docker 和 Docker Compose:

bash 复制代码
# 安装 Docker
curl -fsSL https://get.docker.com | sh

# 验证安装
docker --version
docker compose version

准备一个域名,例如 ntfy.example.com,将 DNS A 记录指向服务器 IP。

安装 Caddy:

bash 复制代码
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update && sudo apt install caddy -y

docker-compose.yml

创建部署目录:

bash 复制代码
mkdir -p /opt/ntfy/{config,cache}
cd /opt/ntfy

创建 docker-compose.yml

yaml 复制代码
version: "3.8"

services:
  ntfy:
    image: binwiederhier/ntfy:latest
    container_name: ntfy
    command: serve
    environment:
      - TZ=Asia/Shanghai
    volumes:
      - ./config:/etc/ntfy
      - ./cache:/var/cache/ntfy
    ports:
      - "127.0.0.1:8088:80"
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "wget -q --tries=1 http://localhost:80/v1/health -O - | grep -Iq \"healthy\":true"]
      interval: 60s
      timeout: 10s
      retries: 3
      start_period: 40s

创建 ntfy 服务端配置文件 /opt/ntfy/config/server.yml

yaml 复制代码
# 服务器基础地址(用于生成推送链接)
base-url: https://ntfy.example.com

# 消息持久化缓存(断线重连后能收到离线消息)
cache-file: /var/cache/ntfy/cache.db
cache-duration: 24h
cache-startup-queries: |
  pragma journal_mode = WAL;
  pragma synchronous = normal;

# 用户认证(强烈建议开启,防止陌生人滥用)
auth-file: /var/cache/ntfy/auth.db
auth-default-access: deny-all     # 默认拒绝所有未认证访问

# 附件支持(发送图片、文件)
attachment-cache-dir: /var/cache/ntfy/attachments
attachment-total-size-limit: 5G
attachment-file-size-limit: 15M
attachment-expiry-duration: 3h

# 消息限制
message-size-limit: 4096
visitor-subscription-limit: 30
visitor-request-limit-burst: 60
visitor-request-limit-replenish: 10s

# Web 界面
web-root: app
enable-signup: false       # 禁止通过 Web 界面自助注册
enable-login: true

启动服务:

bash 复制代码
docker compose up -d

配置说明

Caddy 反向代理

编辑 /etc/caddy/Caddyfile

复制代码
ntfy.example.com {
    reverse_proxy localhost:8088
}

重载 Caddy:

bash 复制代码
sudo systemctl reload caddy

创建用户

ntfy 服务启动后,通过命令行创建用户:

bash 复制代码
# 创建管理员(可以管理所有 topic)
docker exec -it ntfy ntfy user add --role=admin admin

# 创建普通用户
docker exec -it ntfy ntfy user add alice

# 查看用户列表
docker exec -it ntfy ntfy user list

设置 topic 访问权限

bash 复制代码
# 允许用户 alice 对 topic "alerts" 有读写权限
docker exec -it ntfy ntfy access alice alerts rw

# 允许用户 alice 读取 topic "server-logs"
docker exec -it ntfy ntfy access alice server-logs ro

# 允许所有人(包括未认证)订阅某个 topic(公开 topic)
docker exec -it ntfy ntfy access everyone public-announcements ro

消息优先级说明

ntfy 支持五个优先级,影响通知的声音和展示方式:

优先级 Header 值 效果
最高 max / urgent 持续振动报警,直到确认
high 高优先级通知声
普通 default 标准通知
low 无声通知
最低 min 仅出现在通知中心,无提示

使用方法

基础发送(curl)

bash 复制代码
# 最简单的方式
curl -d "服务器备份完成" https://ntfy.example.com/my-alerts

# 带认证
curl -u alice:密码 \
  -d "部署完成" \
  https://ntfy.example.com/my-alerts

# 使用 Access Token(推荐)
curl \
  -H "Authorization: Bearer tk_xxxxxxxxxxxxx" \
  -d "消息内容" \
  https://ntfy.example.com/my-alerts

生成 Access Token

bash 复制代码
# 为用户 alice 创建 Access Token
docker exec -it ntfy ntfy token add alice

# 输出示例:
# token tk_AgQdq7mVBoFD37zQVN29RhuMzNIz2, never expires

发送带标题和标签的通知

bash 复制代码
curl \
  -H "Authorization: Bearer tk_xxxxxxxxxxxxx" \
  -H "Title: 服务器告警" \
  -H "Priority: high" \
  -H "Tags: rotating_light,computer" \
  -d "磁盘使用率已超过 90%,请及时处理" \
  https://ntfy.example.com/server-alerts

在备份脚本中使用

bash 复制代码
#!/bin/bash
NTFY_URL="https://ntfy.example.com/my-alerts"
NTFY_TOKEN="tk_xxxxxxxxxxxxx"

notify() {
  local title="$1"
  local body="$2"
  local priority="${3:-default}"
  curl -s \
    -H "Authorization: Bearer $NTFY_TOKEN" \
    -H "Title: $title" \
    -H "Priority: $priority" \
    -d "$body" \
    "$NTFY_URL" > /dev/null
}

# 执行备份
if tar czf /backup/data-$(date +%Y%m%d).tar.gz /data/; then
  notify "备份成功" "今日备份已完成:/backup/data-$(date +%Y%m%d).tar.gz" "default"
else
  notify "备份失败" "备份脚本执行失败,请立即检查服务器日志!" "urgent"
fi

配合 cron 使用

bash 复制代码
# 编辑 crontab
crontab -e

# 凌晨 2 点执行备份,失败时发送通知
0 2 * * * /opt/scripts/backup.sh || curl -s -u alice:密码 \
  -H "Title: 定时备份失败" -H "Priority: urgent" \
  -d "凌晨备份任务失败!" https://ntfy.example.com/server-alerts

手机 App 订阅

  1. 下载 ntfy 官方 App:
    • Android:Google Play 搜索 "ntfy" 或从 F-Droid 安装
    • iOS:App Store 搜索 "ntfy"
  2. 打开 App → 设置 → 添加自定义服务器:https://ntfy.example.com
  3. 输入用户名和密码(或 Access Token)
  4. 订阅 topic,例如 my-alerts
  5. 发送测试消息,确认手机收到推送

Web 界面

访问 https://ntfy.example.com 可以打开 ntfy 的 Web 界面,支持:

  • 查看历史消息
  • 订阅 topic
  • 发送测试消息
  • 管理 Access Token

常见问题

Q:发送通知返回 403 Forbidden?

说明 topic 需要认证但请求没有携带凭据。检查:

  • 是否在请求中加了 -u user:password-H "Authorization: Bearer token"
  • 用户是否有该 topic 的写权限(ntfy access username topic-name rw

Q:手机收不到推送通知?

  • 检查手机 App 是否允许后台通知权限(各品牌 Android 手机可能需要单独设置)
  • iOS 用户需要确认 App 通知权限已开启
  • 检查 topic 名称是否拼写正确(区分大小写)
  • 使用 Web 界面或 curl 验证消息是否发送成功

Q:如何发送带操作按钮的通知?

ntfy 支持在通知中添加操作按钮:

bash 复制代码
curl \
  -H "Authorization: Bearer $NTFY_TOKEN" \
  -H "Title: 服务器 CPU 过高" \
  -H "Actions: view, 查看详情, https://monitor.example.com; \
               http, 重启服务, https://api.example.com/restart, method=POST" \
  -d "CPU 使用率持续 30 分钟超过 95%" \
  https://ntfy.example.com/server-alerts

Q:消息历史保留多久?

cache-duration 配置控制,本文设置为 24h。客户端离线后重连,会接收到缓存期内的离线消息。超出缓存时间的消息会被自动清理。


ntfy 的核心优势是极简------发送通知不需要任何预先配置,一条 curl 命令搞定;接收通知只需要 App 订阅一个 topic。把它接入备份脚本、监控系统、部署流程,就有了一套属于自己的服务器消息推送中心。

相关推荐
小林ixn2 小时前
从拼多多手机号验证到模板引擎:深入正则表达式与 JS 字符串处理
开发语言·javascript·正则表达式
周末也要写八哥2 小时前
线程的生命周期之线程睡眠
java·开发语言·jvm
炸薯条!2 小时前
二叉树的链式表示(2)
java·数据结构·算法
右耳朵猫AI2 小时前
Python周刊2026W22 | Django 6.1 Alpha 1发布、Nuitka 4.1发布、PEP 831终稿、PEP 808已接受
开发语言·python·django
半个烧饼不加肉2 小时前
JS 底层探究-- 普通函数和构造函数
开发语言·javascript·原型模式
徐寿春2 小时前
什么是数据倾斜
java·guava
小白不白1112 小时前
C# WinForm 与 VP 二次开发
开发语言·c#
李白的天不白2 小时前
一个服务器可以搭建多个网站
java·tomcat
●VON2 小时前
AtomGit Flutter鸿蒙客户端:共享组件
java·flutter·华为·harmonyos·鸿蒙