跳轉至

ntfy

概述

ntfy(讀作 notify)係一套開源嘅輕量推送服務,採用 pub/sub 模型,任何用戶只要向指定 Topic 發送 HTTP 請求,訂閱咗該 Topic 嘅客戶端就會即時收到推送通知。喺 benhoweb 基礎設施入面,ntfy 主要負責以下場景:

  • 備份失敗警報:例如 PostgreSQL 備份任務、檔案系統快照完成後,透過 curl 或脚本向 ntfy 發送結果。
  • 系統告警通知:將 Prometheus Alertmanager 嘅 webhook 指向 ntfy,當服務異常或磁碟用量超標時推送告警。
  • 自動化流程通知:CI/CD pipeline 完成、Infisical 密鑰輪換、容器重啟等事件,統一經 ntfy 集中推送。

公開訂閱端點為 https://ntfy.benhoweb.com,任何具備該域名存取權限嘅客戶端都可以訂閱或發佈訊息。Topic 命名採用 /backup, /alerts, /deploy 等結構,方便分類管理。由於預設唔設存取控制,所有 Topic 均可匿名讀寫,因此只建議用於非敏感通知;如需權限控制,可以啟用 ntfy 內建嘅 users 同 access control list(ACL)。

架構

ntfy 以單一 Docker 容器運行,鏡像為 binwiederhier/ntfy:latest,容器名稱固定為 ntfy。對外流量經 Cloudflare Tunnel 進入,唔需要開啟主機端口或設定 NAT 規則。Cloudflare Tunnel 將 ntfy.benhoweb.com 嘅 HTTPS 請求轉發到容器固定 IP 172.21.0.39:80,容器喺內部網絡 cf_network 上監聽 HTTP 80 端口。

容器依賴以下外部資源:

  • /usr/share/zoneinfo(唯讀掛載):確保容器可以使用香港時區(Asia/Hong_Kong)。
  • /opt/docker/ntfy/cache:存放 ntfy 嘅訊息緩存資料庫(SQLite)、附件等。
  • /opt/docker/ntfy/config:存放 ntfy.yml 主配置、auth.db 用戶資料庫及憑證。

ntfy 本身使用 SQLite 儲存訊息,無需外部資料庫;但若日後需要高可用或橫向擴展,可以切換至 PostgreSQL,因此喺設計上保留咗 PostgreSQL 作為可選依賴。

網絡層面,容器接入已存在嘅外部 Docker network cf_network(bridge 模式),並指定靜態 IPv4 172.21.0.39。此安排令到 Cloudflare Tunnel 或其他內部服務可直接用固定 IP 訪問,唔會因容器重建而變更地址。同一網絡內仲有其他服務(例如 LiteLLM、Qdrant),佢哋之間可以透過內部 IP 互相存取,唔經過公開互聯網。

部署(Docker Compose 片段)

以下係精簡可用嘅 docker-compose.yml,直接對應生產環境部署:

services:

  ntfy:
    image: binwiederhier/ntfy:latest
    container_name: ntfy
    restart: unless-stopped

    command:
      - serve

    environment:
      TZ: Asia/Hong_Kong
      # 以下變數可按實際環境需要調整,敏感值由 Infisical 注入
      NTFY_BASE_URL: "https://ntfy.benhoweb.com"
      NTFY_CACHE_FILE: "/var/cache/ntfy/cache.db"
      NTFY_AUTH_FILE: "/etc/ntfy/auth.db"
      NTFY_LISTEN_HTTP: ":80"

    volumes:
      - /usr/share/zoneinfo:/usr/share/zoneinfo:ro
      - /opt/docker/ntfy/cache:/var/cache/ntfy
      - /opt/docker/ntfy/config:/etc/ntfy

    networks:
      cf_network:
        ipv4_address: 172.21.0.39

networks:
  cf_network:
    external: true

部署步驟:

# 確保外部網絡存在(若未建立)
docker network create cf_network

# 建立目錄
mkdir -p /opt/docker/ntfy/{cache,config}

# 啟動服務
docker compose up -d ntfy

構建完成後,使用 docker compose logs -f ntfy 嚟確認服務已正常啟動。

配置與環境變數

ntfy 支援透過環境變數或 /etc/ntfy/ntfy.yml 進行設定。上述 compose 中,/opt/docker/ntfy/config 掛載至 /etc/ntfy,因此設定檔路徑為 /opt/docker/ntfy/config/ntfy.yml。以下係常用環境變數:

變數 用途 範例
TZ 時區設定 Asia/Hong_Kong
NTFY_BASE_URL 對外公開嘅 base URL,用於生成附件連結等 https://ntfy.benhoweb.com
NTFY_LISTEN_HTTP HTTP 監聽地址,預設為 :80 :80
NTFY_CACHE_FILE 訊息緩存 SQLite 資料庫位置 /var/cache/ntfy/cache.db
NTFY_AUTH_FILE 用戶認證資料庫位置 /etc/ntfy/auth.db
NTFY_AUTH_DEFAULT_ACCESS 預設存取權限(deny-allallow-all allow-all
NTFY_ENABLE_LOGIN 是否允許密碼登入 true
NTFY_BEHIND_PROXY 若位於反向代理/Cloudflare 後面,設為 true true

在真實部署中,所有敏感設定(例如 auth token、管理員密碼)都係經由 Infisical 管理,透過 CI/CD 系統注入到容器環境,並唔會直接寫入 docker-compose.yml 或 git repository。

ntfy 支援透過 ntfy user addntfy access 命令管理用戶權限。例如:

# 建立用戶
docker exec -it ntfy ntfy user add --password '...' admin

# 設定 topic 權限
docker exec -it ntfy ntfy access admin '*'

注意:如果啟用咗認證,預設 allow-all 要改為 deny-all,並逐個 Topic 配發權限。

維運與監控

日常維運檢查建議包括:

  1. 容器狀態:檢查容器是否長期運行且無重啟。

    docker ps --filter name=ntfy
    docker compose ps
    

  2. 日誌:查看有冇異常錯誤(例如權限問題、端口衝突)。

    docker compose logs --tail=200 -f ntfy
    

  3. 健康檢查:ntfy 本身未有內建 healthcheck,但可以利用 /v1/health 端點(需要啟用)或者直接發一個測試請求:

    curl -sS -o /dev/null -w "%{http_code}\n" http://172.21.0.39:80/v1/health
    curl -sS -o /dev/null -w "%{http_code}\n" https://ntfy.benhoweb.com/v1/health
    

  4. 發送測試通知

    curl -d "test from wiki" ntfy.benhoweb.com/wiki-test
    

  5. 監控指標:ntfy 預設提供 Prometheus metrics 端點 /metrics,可以加入 Prometheus 抓取任務,例如:

    scrape_configs:
      - job_name: ntfy
        static_configs:
          - targets: ["172.21.0.39:80"]
    
    配合 Grafana dashboard 監控訊息發送量、連線失敗、topic 數目等。

  6. 備份/opt/docker/ntfy/cache 內嘅 cache.db 包含近期訊息,建議每日進行備份(例如使用 rsync

常見問題

  • Topic 權限點設?ntfy access 指令,預設 allow-alldeny-all 再逐個 Topic 授權。
  • 推送冇收到? 檢查 Cloudflare Tunnel 到 172.21.0.39 是否通,睇 docker compose logs ntfy 有冇 auth 錯誤。
  • 訊息會保留幾耐? 預設 cache 24h,可喺 ntfy.yml 調 cache-duration

相關鏈接