Notifo v1.3.0 配置参数详解
Notifo 1.3.0 配置参数详解:配置加载优先级、appsettings 逐组默认值与取值约束、环境变量双下划线转换规则与三种场景推荐组合,全部实测验证。
Notifo v1.3.0 配置参数详解
目标:把 Notifo 1.3.0 的全部配置项讲透——配置加载体系与优先级、appsettings.json 逐组参数的默认值与取值约束、环境变量转换规则,以及按场景(最小单机/生产 SMTP/多实例集群)的推荐组合。参数默认值取自官方 1.3.0 源码中的
appsettings.json,行为描述均在本地容器实测验证(2026-10-30)。
一、环境信息
| 项目 | 内容 |
|---|---|
| 组件版本 | Notifo 1.3.0(镜像 squidex/notifo:1.3.0,运行时 .NET 7.0.0,实测 docker inspect 确认) |
| 配置体系 | ASP.NET Core 标准 IConfiguration:JSON 分层键 + 环境变量双下划线覆盖 |
| 参考文件 | 官方源码 backend/src/Notifo/appsettings.json(tag 1.3.0) |
| 实测环境 | Docker Compose 三容器(notifo + mongo:5 + mailhog),宿主端口 8151 |
二、配置体系总览
Notifo 没有独立的配置 Web 界面,全部配置走三条通道,优先级从高到低:
- 环境变量:双下划线
__表示层级,例如IDENTITY__USERS__0__EMAIL对应 JSON 键identity:users[0]:email(0为数组下标)。这是容器部署的主通道; - appsettings.Production.json:挂载到
/app/appsettings.Production.json即可覆盖镜像内置默认值,适合固化不常改动的大块配置; - appsettings.json(镜像内置):所有参数的默认值来源,本文以它为基准逐组讲解。
💡 实测技巧:想确认容器「最终看到」的某个配置,可以直接
docker inspect <容器名> --format '{{json .Config.Env}}'比对环境变量,或docker exec <容器名> cat /app/appsettings.json查看内置默认。运行态验证手段见第六节。
三、核心参数组详解
3.1 urls —— 对外地址(必配)
| 参数 | 默认值 | 说明 |
|---|---|---|
urls:baseUrl | https://localhost:5002 | 对外访问基础地址;邮件链接、trackSeenUrl/trackDeliveredUrl、邮件偏好链接均以此为前缀。环境变量 URLS__BASEURL,容器部署必改(实测通知接口返回的跟踪 URL 与该值逐字拼接) |
urls:callbackUrl | 空 | Webhook 出站回调的覆盖地址;留空则使用 baseUrl |
3.2 storage —— 存储后端(必配,仅 MongoDB)
| 参数 | 默认值 | 说明 |
|---|---|---|
storage:type | MongoDB | 官方唯一支持的存储类型,无需改动 |
storage:mongoDB:connectionString | mongodb://localhost | Mongo 连接串。容器部署示例:mongodb://notifo-mongo(Compose 服务名直连,实测可用) |
storage:mongoDB:databaseName | Notifications | 业务库名。实测默认库名确为 Notifications,直查 Mongo 可见 Apps/Users/Subscriptions/Notifications/Topics/Queue_events 等集合 |
3.3 messaging —— 消息队列与调度
| 参数 | 默认值 | 说明 |
|---|---|---|
messaging:type | Scheduler | 支持 Scheduler(内置,单机)/ RabbitMq / Kafka / GooglePubSub。单机默认即可;多实例部署必须换外部队列 |
messaging:rabbitMq:uri | amqp://guest:guest@localhost/ | RabbitMQ 连接串 |
messaging:kafka:bootstrapServers | localhost:9092 | Kafka 接入点 |
messaging:kafka:groupId | service | 消费组 ID;同组多实例形成竞争消费 |
messaging:kafka:saslUsername/Password/Mechanism/SecurityProtocol | 空 / 空 / Plain / SaslSsl | Kafka SASL 认证 |
messaging:googlePubSub:projectId / prefix | 空 / test-notifo- | Google PubSub 项目与主题前缀 |
💡 实测印证:默认 Scheduler 模式下,Mongo 的
Queue_events(事件队列)与Scheduler_email/webpush/webhook/...(每渠道调度集合)在发布通知后会短暂出现记录,处理完成即消费,这就是内置调度的实现位置。
3.4 clustering —— 多实例协调
| 参数 | 默认值 | 说明 |
|---|---|---|
clustering:type | None | 支持 None / Redis。多实例时设为 Redis |
clustering:redis:connectionString | localhost | Redis 连接串 |
3.5 assetStore —— 资产存储
| 参数 | 默认值 | 说明 |
|---|---|---|
assetStore:type | Folder | 支持 Folder / MongoDb(GridFS) / GoogleCloud / AzureBlob / AmazonS3 / FTP(官方标注不推荐) |
assetStore:folder:path | Assets | 本地目录(容器内 /app/Assets,官方镜像即按此挂载持久化) |
assetStore:mongoDb:bucket | fs | GridFS 桶名 |
assetStore:amazonS3:* | bucket: notifo-assets、regionName: eu-central-1 等 | S3 兼容存储配置(含 serviceUrl 可指向 MinIO 等自建 S3) |
assetStore:azureBlob:containerName / connectionString | notifo-assets / UseDevelopmentStorage=true | Azure Blob 配置 |
3.6 identity —— 认证与初始账号(部署必看)
| 参数 | 默认值 | 说明 |
|---|---|---|
identity:allowPasswordAuth | true | 本地密码登录开关;置 false 仅保留第三方 OAuth 登录 |
identity:users[n]:email / password | admin@notifo.io / 空 | 初始管理员,容器启动时自动创建。环境变量写法:IDENTITY__USERS__0__EMAIL、IDENTITY__USERS__0__PASSWORD(实测该账号首登即用,无需注册流程) |
identity:adminClientId / adminClientSecret | 空 | OAuth client_credentials 客户端。配置后可用 POST /connect/token(grant_type=client_credentials&scope=NotifoAPI)换取 Bearer token 供自动化脚本使用;实测 token 有效期 expires_in: 2592000(30 天),为 JWE 加密格式 |
identity:githubClient / githubSecret | 官方内置演示值 | GitHub 登录 OAuth 凭据,生产环境必须替换或置空(置空即隐藏该登录入口) |
identity:googleClient / googleSecret | 官方内置演示值 | Google 登录 OAuth 凭据,同上 |
identity:microsoftClient / microsoftSecret | 空 | Microsoft 登录 OAuth 凭据 |
⚠️ 安全提醒:镜像内置的 GitHub/Google 演示凭据是公开信息,部署后请一律置空或更换;初始管理员密码
Q1w2e3r4!也应在首登后修改或改用随机值环境变量。
3.7 webPush —— 浏览器推送(Web Push 渠道必配)
| 参数 | 默认值 | 说明 |
|---|---|---|
webPush:subject | https://notifo.io | VAPID subject,应为你的站点 URL |
webPush:vapidPublicKey / vapidPrivateKey | 官方演示密钥对 | Web Push VAPID 密钥对,生产环境必须生成自己的密钥对替换(可用 npx web-push generate-vapid-keys) |
3.8 sms / email —— 渠道级凭据
| 参数 | 默认值 | 说明 |
|---|---|---|
sms:messageBird:phoneNumber / accessKey | 空 | MessageBird 短信渠道全局凭据 |
email:amazonSES:host | email-smtp.eu-central-1.amazonaws.com | Amazon SES SMTP 主机 |
email:amazonSES:username / password | 空 | SES SMTP 凭据 |
email:amazonSES:awsAccessKeyId / awsSecretAccessKey | 空 | SES API 凭据 |
💡 注意分层:这组是「全局/服务商级」凭据;而 App 内的 Email 发件服务器(如自建 SMTP、Mailhog)在 Dashboard 的 Integrations 里按 App 配置,两者不冲突——实测同一实例里 App 级 SMTP 指向 Mailhog 正常收信,无需动这组全局参数。
3.9 web —— 实时通道(SignalR)
| 参数 | 默认值 | 说明 |
|---|---|---|
web:signalR:enabled | true | Web 端实时通知开关 |
web:signalR:sticky | false | 多实例负载均衡下设 true(需会话粘滞);不支持粘滞的环境请关闭 SignalR 走轮询 |
web:signalR:pollingInterval | 5000 | 未用 SignalR 时的轮询间隔(毫秒) |
3.10 diagnostics —— 诊断与自愈
| 参数 | 默认值 | 说明 |
|---|---|---|
diagnostics:dumpTool / gcdumpTool | 空(官方镜像自动置为 /tools/dotnet-dump、/tools/dotnet-gcdump,实测 env 可见) | .NET 诊断工具路径 |
diagnostics:dumpTriggerInMB / gcumpTriggerInMB | 0(关闭) | 内存超过阈值自动生成 dump/gcdump 并写入资产存储 |
diagnostics:gc:threshold | 8192 | 进程内存上限(MB),超过则 /healthz 判定不健康。实测 healthz 输出原文即「Application must consume less than 8 GB memory.」 |
3.11 logging —— 日志
| 参数 | 默认值 | 说明 |
|---|---|---|
logging:logLevel:default | Information(Microsoft: Warning) | 标准 .NET 日志级别 |
logging:otlp:enabled / endpoint / sampling | false / 空 / 1.0 | OpenTelemetry 导出 |
logging:stackdriver:enabled | false | GCP Stackdriver 导出 |
logging:applicationInsights:enabled / connectionString | false / 演示串 | Azure App Insights 导出 |
3.12 其他
| 参数 | 默认值 | 说明 |
|---|---|---|
ASPNETCORE_URLS | 镜像内置 http://+:5000 | Kestrel 监听地址;改容器内端口时同步改 healthcheck |
allowedHosts | * | ASP.NET Core Host 过滤,反代场景按需收紧 |
四、环境变量转换规则与部署全量对照
转换规则只有一条:JSON 路径用双下划线拼接,数组用数字下标。部署篇 compose 里的全部环境变量与语义对照如下(均为实测生效值):
| 环境变量 | 对应 JSON 键 | 作用 |
|---|---|---|
URLS__BASEURL=http://192.168.1.200:8151 | urls:baseUrl | 对外地址/链接前缀 |
STORAGE__MONGODB__CONNECTIONSTRING=mongodb://notifo-mongo | storage:mongoDB:connectionString | Mongo 连接 |
ASPNETCORE_URLS=http://+:5000 | Kestrel 配置 | 容器内监听 |
IDENTITY__USERS__0__EMAIL=admin@notifo.io | identity:users[0]:email | 初始管理员邮箱 |
IDENTITY__USERS__0__PASSWORD=Q1w2e3r4! | identity:users[0]:password | 初始管理员密码 |
IDENTITY__ADMINCLIENTID=notifo-admin | identity:adminClientId | 自动化用 OAuth 客户端 |
IDENTITY__ADMINCLIENTSECRET=q1w2e3r4 | identity:adminClientSecret | 同上 |
IDENTITY__GITHUBCLIENT=__(等四组) | identity:githubClient/Secret 等 | 第三方登录,置空即禁用 |
五、按场景推荐配置
场景 A:最小单机(测试/演示) —— 部署篇 compose 原样即可:内置 Scheduler + Folder 资产 + Mailhog 收信验证,零外部依赖。
场景 B:生产单机(真实发信) —— 在 A 基础上:URLS__BASEURL 换正式域名;App 内配置真实 SMTP 或启用全局 email:amazonSES;webPush:vapid* 换自有密钥对;初始管理员密码改强随机值;IDENTITY__GITHUB/GOOGLE/MICROSOFT* 置空;数据目录纳入备份(见部署篇第五节)。
场景 C:多实例高可用 —— clustering:type=Redis + messaging:type=RabbitMq(或 Kafka,注意 groupId 一致形成竞争消费)+ web:signalR:sticky=true(负载均衡开粘滞会话)+ assetStore 换共享后端(S3/GridFS,不能用本地 Folder)+ Mongo 副本集。四项缺一都会出现通知偶发丢失或 Web 通道断连。
六、参数校验与生效验证方法
配置改完如何确认「真的生效」?以下命令全部实测可用:
# 1) 健康与内存阈值:status=Healthy 且 gc 描述包含 threshold 对应文字
curl -s http://localhost:8151/healthz | python3 -m json.tool
# 2) 轻量探活
curl -s http://localhost:8151/ping
# 3) 库名验证:列出实际使用的库与集合
docker exec notifo-1-3-0-stack-notifo-mongo-1 mongosh --quiet \
--eval 'db.getSiblingDB("Notifications").getCollectionNames().join(",")'
# 4) client_credentials 验证(identity:adminClient* 配置正确即返回 token)
curl -s -X POST http://localhost:8151/connect/token \
-d "grant_type=client_credentials&client_id=notifo-admin&client_secret=q1w2e3r4&scope=NotifoAPI"
# 5) 链接前缀验证:发布一条通知后,检查返回里的 trackSeenUrl 是否以 BASEURL 开头
curl -s -H "X-ApiKey: <AppKey>" "http://localhost:8151/api/apps/{appId}/notifications?take=1"
环境变量改动需 docker compose up -d(重建容器)生效;appsettings.Production.json 改动同样需要重启容器进程。
七、常见问题(FAQ)
Q1:环境变量写了却不生效?
三个高频原因:① 双下划线写成了单下划线;② 数组下标越界(USERS__1__EMAIL 但只初始化到 0 位不会自动扩位);③ 改完没有重建容器(docker compose restart 不重读 env,需 up -d)。
Q2:URLS__BASEURL 能否填 localhost?
仅当所有用户都在本机访问时可以。邮件里的链接由服务端拼好发给收件人,收件人机器上的 localhost 不是服务器——必须用外部可达的 IP/域名(实测邮件偏好链接、跟踪链接均直接拼 BASEURL)。
Q3:Web Push 通知发不出去?
检查 webPush:vapid* 是否还是官方演示密钥;浏览器端授权站点与 VAPID subject 需匹配,且 baseUrl 必须是 HTTPS(浏览器 Push API 的硬性要求)。
Q4:想换端口怎么办?
只改宿主映射即可(ports: "8151:5000" 左侧),容器内 5000 与 healthcheck 不用动;同时把 URLS__BASEURL 的端口同步成宿主端口。
Q5:内存阈值可以调吗?
可以,diagnostics:gc:threshold 单位 MB。小内存机器下调到如 1024,内存超限时 healthz 会转不健康,便于被编排系统感知重启。