Notifo v1.3.0 Docker Compose 部署指南

Notifo 1.3.0 Docker Compose 三容器部署实测:MongoDB 与 Mailhog 配套、健康检查与管理员初始化、SMTP 集成收信验证、数据持久化、环境变量表与常见问题。

NotifoNotifoDockerMongoDB2026/10/30

Notifo v1.3.0 Docker Compose 部署指南

目标:用一份经过实测的 docker-compose.yml,把 Notifo 1.3.0 主服务、MongoDB 与 Mailhog(本地 SMTP 模拟器)三容器拉起,完成健康检查、管理员登录、首个 App 创建与 Email 渠道收信验证。本文所有命令与回显均在 Docker Compose v2 环境实测通过(2026-10-30)。

一、环境信息

项目内容
组件版本Notifo 1.3.0(squidex/notifo:1.3.0,截至 2026-10-30 的最新正式版)
容器运行时Docker + Docker Compose v2(docker compose 子命令)
实测宿主端口Notifo 8151(容器 5000)、Mailhog UI 8150(容器 8025)
MongoDBmongo:5(官方文档推荐与实测配套版本,容器内 27017)
Mailhogmailhog/mailhog(SMTP 1025 + Web UI 8025,仅用于测试收信)
操作系统Linux x86_64(宿主)

二、镜像选型说明

镜像角色选型依据
squidex/notifo:1.3.0通知主服务(ASP.NET Core 7)官方唯一镜像;内部自带健康检查 curl -f http://localhost:5000/healthz(实测 docker inspect 可见该定义)
mongo:5必备存储Notifo 仅支持 MongoDB;官方 docker-compose 模板即使用 mongo:5,实测 1.3.0 与其兼容
mailhog/mailhogSMTP 模拟器(可选)生产环境换成真实 SMTP/SES;测试环境用 Mailhog 在 8025 端口网页收信,验证 Email 渠道零成本

💡 Notifo 容器内置 dotnet-counters、dotnet-dump 等诊断工具(环境变量 DIAGNOSTICS__* 指向 /tools/),排障时可 docker exec 直接使用,无需换镜像。

三、前置条件

  1. 宿主已安装 Docker 与 Docker Compose v2;
  2. 端口未被占用:8151(Notifo)、8150(Mailhog UI);
  3. 准备工作目录 notifo/,其下将创建 docker-compose.yml 与 data/ 数据目录;
  4. 明确对外访问地址(下文以 http://192.168.1.200:8151 为例),必须与浏览器实际访问地址一致,否则邮件里的跟踪/偏好链接会指向错误主机。

四、部署步骤

1)编写 docker-compose.yml

name: notifo-1-3-0-stack

services:
  notifo-mongo:
    image: mongo:5
    volumes:
      - ./data/mongo:/data/db
    networks:
      - notifo-net
    restart: unless-stopped

  notifo:
    image: "squidex/notifo:1.3.0"
    ports:
      - "8151:5000"
    environment:
      - URLS__BASEURL=http://192.168.1.200:8151
      - STORAGE__MONGODB__CONNECTIONSTRING=mongodb://notifo-mongo
      - ASPNETCORE_URLS=http://+:5000
      - IDENTITY__USERS__0__EMAIL=admin@notifo.io
      - IDENTITY__USERS__0__PASSWORD=Q1w2e3r4!
      - IDENTITY__ADMINCLIENTID=notifo-admin
      - IDENTITY__ADMINCLIENTSECRET=q1w2e3r4
      - IDENTITY__GOOGLECLIENT=
      - IDENTITY__GOOGLESECRET=
      - IDENTITY__GITHUBCLIENT=
      - IDENTITY__GITHUBSECRET=
      - IDENTITY__MICROSOFTCLIENT=
      - IDENTITY__MICROSOFTSECRET=
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:5000/healthz"]
      start_period: 60s
    depends_on:
      - notifo-mongo
    volumes:
      - ./data/assets:/app/Assets
    networks:
      - notifo-net
    restart: unless-stopped

  notifo-mailhog:
    image: mailhog/mailhog
    ports:
      - "8150:8025"
    networks:
      - notifo-net
    restart: unless-stopped

networks:
  notifo-net:
    driver: bridge
    ipam:
      config:
        - subnet: 10.89.81.0/24

要点:

  • URLS__BASEURL 按你的实际 IP/域名修改,邮件正文与跟踪链接全部以它为前缀(实测通知接口返回的 trackSeenUrl 即该前缀);
  • IDENTITY__USERS__0__* 定义初始管理员(首个登录账号),IDENTITY__ADMINCLIENT* 定义 OAuth client_credentials 客户端供自动化脚本使用(实测可换 token);
  • 邮箱渠道的 SMTP 服务器不在环境变量里配置,而是登录后在 App 的 Settings → Email integration 中按 App 配置(见步骤 4)。

2)启动与自检

docker compose up -d
docker compose ps        # 等待 notifo 状态变为 Up (healthy),约 30~60 秒
curl -s http://localhost:8151/healthz

实测 /healthz 正常回显(节选):

{"entries":{"gc":{"data":{"Gen0CollectionCount":307,"HeapSizeBytes":42444368,
"WorkingSetString":"457.1 MB"},"description":"Application must consume less than 8 GB memory.",
"status":"Healthy"}},"status":"Healthy"}

3)登录管理界面并创建 App

  1. 浏览器打开 http://192.168.1.200:8151,用 admin@notifo.io / Q1w2e3r4! 登录;
  2. Dashboard → Apps → 新建 App(如 demo),创建成功后 App 页会展示 4 把 API Key(Admin/WebManager 各两把);
  3. 记录一把 Admin 角色的 API Key,后续 API 调用使用 X-ApiKey 头携带(认证细节见《Notifo v1.3.0 API 使用详解》)。

4)配置 Email 集成(对接 Mailhog)并实测收信

  1. App → Settings → Integrations → 新增 SMTP 集成,填入:
    • host: notifo-mailhog(Compose 网络内的服务名)
    • port: 1025
    • fromEmail: notifo@example.com,fromName: Notifo Demo
  2. 保存后集成状态即显示 Verified(实测:SMTP 集成即时探活);
  3. 通过 API 建一个用户并发布一条通知(命令见 API 篇),几秒后在 Mailhog 界面 http://192.168.1.200:8150 应看到主题为 Your notifications from demo 的摘要邮件——这就是 Notifo 的邮件摘要(digest)机制在工作,实测正文逐条列出通知标题与内容,并附「更改邮件偏好」链接(指向 $URLS__BASEURL/api/email-preferences?...)。

⚠️ 若通知列表里 Email 渠道状态为 Skipped,且系统日志出现 EMAIL: Cannot find template 'Unnamed'.,说明该通知发布时 Email 集成尚未启用或模板缺失——先完成本步再发布即可(实测复现过该报错)。

五、数据持久化说明

数据容器内路径宿主挂载说明
MongoDB 全部业务数据/data/db./data/mongoApp/用户/订阅/通知/模板/日志全在这里,库名默认 Notifications
资源文件(Assets)/app/Assets./data/assets通知图片等媒体资源,默认 assetStore 类型为 Folder

备份策略(实测可用):

# 备份:逻辑导出 Mongo + 打包 assets
docker exec notifo-1-3-0-stack-notifo-mongo-1 mongodump --archive --gzip > notifo-mongo-$(date +%F).archive.gz
tar czf notifo-assets-$(date +%F).tgz data/assets

# 恢复:空库导入后重启主服务
docker exec -i notifo-1-3-0-stack-notifo-mongo-1 mongorestore --archive --gzip < notifo-mongo-2026-10-30.archive.gz

六、环境变量表

环境变量示例值说明
URLS__BASEURLhttp://192.168.1.200:8151对外访问地址,邮件链接/跟踪 URL 的前缀,必改
URLS__CALLBACKURL空Webhook 回调地址覆盖(一般留空)
STORAGE__MONGODB__CONNECTIONSTRINGmongodb://notifo-mongoMongo 连接串,服务名即主机名
STORAGE__MONGODB__DATABASENAME未设(默认 Notifications)自定义库名(实测默认库名)
ASPNETCORE_URLShttp://+:5000Kestrel 监听地址,配合端口映射使用
IDENTITY__USERS__0__EMAILadmin@notifo.io初始管理员邮箱(序号 0 可扩展多个初始用户)
IDENTITY__USERS__0__PASSWORDQ1w2e3r4!初始管理员密码,上线必须更换
IDENTITY__ADMINCLIENTIDnotifo-adminOAuth client_credentials 客户端 ID(自动化用)
IDENTITY__ADMINCLIENTSECRETq1w2e3r4对应密钥,实测可经 /connect/token 换取 Bearer token
IDENTITY__GITHUBCLIENT/SECRET空GitHub 登录 OAuth 凭据(不填则隐藏该登录方式)
IDENTITY__GOOGLECLIENT/SECRET空Google 登录 OAuth 凭据
IDENTITY__MICROSOFTCLIENT/SECRET空Microsoft 登录 OAuth 凭据

💡 双下划线 __ 是 .NET 配置的层级分隔符:IDENTITY__USERS__0__EMAIL 对应 appsettings.json 里的 identity:users[0]:email。全部参数的取值与默认值详见《Notifo v1.3.0 配置参数详解》。

七、配置参数说明

本文只覆盖部署必需的环境变量。Notifo 的完整配置体系(存储、消息队列、资产存储、Web Push VAPID、诊断、日志、SignalR 等)见《Notifo v1.3.0 配置参数详解》,其中包含官方 appsettings.json 的逐组解读与按场景推荐。

八、配置文件挂载

Notifo 的配置除了环境变量,还可以用 .NET 标准的 JSON 覆盖文件:

    volumes:
      - ./data/assets:/app/Assets
      - ./appsettings.Production.json:/app/appsettings.Production.json:ro

覆盖优先级:环境变量 > appsettings.Production.json > appsettings.json(镜像内置)。适合把不常改动的大块配置(如 assetStore、logging)固化成文件、敏感项留给环境变量的混合做法。媒体资源目录 /app/Assets 对应 assetStore:folder:path 的默认值,换其他资产后端(如 Mongo GridFS、S3)时该挂载可去掉。

九、等价 docker run

不使用 Compose 时的等价命令(先建网络):

docker network create notifo-net

docker run -d --name notifo-mongo --network notifo-net \
  -v "$PWD/data/mongo:/data/db" mongo:5

docker run -d --name notifo --network notifo-net \
  -p 8151:5000 \
  -e URLS__BASEURL=http://192.168.1.200:8151 \
  -e STORAGE__MONGODB__CONNECTIONSTRING=mongodb://notifo-mongo \
  -e ASPNETCORE_URLS=http://+:5000 \
  -e IDENTITY__USERS__0__EMAIL=admin@notifo.io \
  -e IDENTITY__USERS__0__PASSWORD='Q1w2e3r4!' \
  -e IDENTITY__ADMINCLIENTID=notifo-admin \
  -e IDENTITY__ADMINCLIENTSECRET=q1w2e3r4 \
  -v "$PWD/data/assets:/app/Assets" \
  --restart unless-stopped \
  squidex/notifo:1.3.0

docker run -d --name notifo-mailhog --network notifo-net \
  -p 8150:8025 --restart unless-stopped mailhog/mailhog

十、常用运维命令

# 健康与服务状态
docker compose ps
curl -s http://localhost:8151/healthz | python3 -m json.tool
curl -s http://localhost:8151/ping          # 轻量探活

# 日志
docker compose logs -f notifo               # 主服务日志(Kestrel 输出)
# App 级投递日志在 Dashboard 的 Logs 页,或 API:GET /api/apps/{appId}/logs

# Mongo 直查(排障利器,实测库名 Notifications)
docker exec notifo-1-3-0-stack-notifo-mongo-1 mongosh --quiet \
  --eval 'db.getSiblingDB("Notifications").getCollectionNames().join(",")'

# 版本升级(1.3.0 已是最新正式版;未来出新版时)
# 1) 编辑 docker-compose.yml:把 image 行改为 Releases 公告的新 tag
# 2) 拉取新镜像并重建服务
docker compose pull notifo && docker compose up -d notifo

# 彻底移除(含数据卷,谨慎)
docker compose down -v

十一、常见问题(FAQ)

Q1:容器一直 unhealthy 或重启? 启动期 60 秒内属正常(start_period: 60s,Mongo 就绪后主服务才开始迁移)。超过 2 分钟仍 unhealthy 时先看 docker compose logs notifo,最常见原因是 Mongo 连接串主机名写错或 8151 端口冲突。

Q2:API 调用一直 401? Notifo 的 API Key 认证使用 X-ApiKey 请求头,而不是 Authorization: Bearer。实测把 App API Key 放进 Bearer 会稳定返回 401;Bearer 只用于 OAuth client_credentials 换来的 token(详见 API 篇认证一节)。

Q3:邮件渠道显示 Skipped,Mailhog 没收到信? 两种实测复现过的原因:① 发布通知时 Email 集成还没配置/未启用;② 无模板且未携带 preformatted 文本,日志报 EMAIL: Cannot find template 'Unnamed'.。先配置 SMTP 集成再发布,或发布时带 preformatted.subject/body。

Q4:邮件里的链接指向错误地址? URLS__BASEURL 与实际访问地址不一致所致。实测跟踪链接(/api/tracking/...)与邮件偏好链接(/api/email-preferences?...)都直接拼接 BASEURL,改完环境变量需重建容器生效。

Q5:发布接口返回 204 但用户没收到通知? 先查该 App 的系统日志:若记录 Event has no subscriber.,说明主题没有匹配的订阅者——确认用户订阅的主题前缀与发布主题一致(实测订阅与发布均返回 204 空体,成败只能靠列表/日志确认)。

Q6:多实例部署要注意什么? 需要同时配置 Redis clustering(clustering:type=Redis)、SignalR sticky session(或 web:signalR:sticky=true)以及外部消息队列(messaging:type 改 Kafka/RabbitMQ/PubSub),单机默认的 Scheduler 模式不支持多副本竞争。

十二、参考链接