Nextcloud AIO 通知容器(Notifications Community Container):实现社区容器向 Nextcloud 用户发送管理员通知
Nextcloud AIO 通知容器(Notifications Community Container):实现社区容器向 Nextcloud 用户发送管理员通知
导读
本篇文章围绕 Nextcloud All-in-One(AIO)仓库中 community-containers/notifications 社区容器展开,讲解如何让其他 AIO 社区容器(例如 Scrutiny 磁盘健康监控)在检测到异常时,自动向 Nextcloud 管理员发送站内通知。读完本文你将掌握该容器的作用、部署配置(notifications.json)的每一项参数含义、其与 Scrutiny 的联动方式,以及 AIO 社区容器的添加、测试与移除流程。
一、Notifications 容器的定位:社区容器间的“通知桥梁”
Nextcloud AIO 官方镜像提供了 notify.sh 与 notify-all.sh 两个脚本,负责在容器内部向 Nextcloud 的管理员(或全部用户)推送站内通知。而 Notifications 社区容器则把这一能力开放给其他社区容器:任何需要向用户告警的 AIO 社区容器,都可以通过它把消息写入 Nextcloud 的通知系统。
根据 community-containers/notifications/readme.md 的说明,该容器允许其他 AIO 社区容器向 Nextcloud 用户发送管理员通知(admin notifications)。典型场景是 Scrutiny 容器(磁盘 SMART 健康状态前端):当 smartctl 检测到磁盘故障时,Scrutiny 会借助 Notifications 容器把告警推送给 Nextcloud 管理员。
其他社区容器(如 Scrutiny)
│ 发现异常(smartctl failure)
▼
nextcloud-aio-notifications 容器
│ 通过 Docker socket 访问 Nextcloud 容器
▼
Nextcloud 站内通知(管理员用户)
二、部署配置逐项解读:notifications.json 全参数说明
该容器在 AIO 社区容器体系中的定义位于 notifications.json,遵循 aio_services_v1 结构。完整内容如下:
{
"aio_services_v1": [
{
"container_name": "nextcloud-aio-notifications",
"display_name": "Notifications",
"documentation": "https://github.com/nextcloud/all-in-one/tree/main/community-containers/notifications",
"image": "ghcr.io/szaimen/aio-notifications",
"image_tag": "v1",
"internal_port": "10000",
"restart": "unless-stopped",
"volumes": [
{
"source": "%WATCHTOWER_DOCKER_SOCKET_PATH%",
"destination": "/var/run/docker.sock",
"writeable": false
}
],
"environment": [
"TZ=%TIMEZONE%"
]
}
]
}
各字段含义如下(字段校验规则可对照 php/containers-schema.json):
container_name:容器名称,必须以nextcloud-aio-前缀开头(schema 要求^nextcloud-aio-[a-z0-9-]+$),此处为nextcloud-aio-notifications。display_name:在 AIO 管理界面中显示的名称,即 “Notifications”。documentation:指向该容器文档的链接,schema 要求以https://开头。image:镜像地址ghcr.io/szaimen/aio-notifications,schema 要求形如^(ghcr.io/)?[a-z0-9/-]+$,即必须托管在 ghcr.io 且仅含小写字母、数字、斜杠与连字符。image_tag:镜像标签v1。internal_port:容器内部服务端口10000,schema 允许([0-9]{1,5})|host|(%[A-Z_]+%)。该端口仅在 AIO 内部网络(nextcloud-aio)中暴露,不会映射到宿主机,因此对外不可见。restart:重启策略,schema 仅允许unless-stopped。volumes:将%WATCHTOWER_DOCKER_SOCKET_PATH%(由 AIO 注入的 Docker socket 路径变量)只读挂载到容器内/var/run/docker.sock,writeable: false保证只读访问,避免社区容器篡改 Docker 守护进程。environment:仅注入TZ=%TIMEZONE%,即沿用 AIO 管理界面中设置的系统时区。
注意:该容器没有声明 ports、cap_add、backup_volumes 等字段,意味着它不对外提供端口、不请求额外内核能力、也不参与 AIO 的备份卷机制(对比 scrutiny.json 中声明的 nextcloud_aio_scrutiny 与 nextcloud_aio_scrutiny_db 备份卷即可看到差异)。
三、通知是怎么发出去的:底层调用链与源码佐证
Notifications 容器并非在 Nextcloud 之外另起一套消息系统,而是通过 Docker socket 进入 Nextcloud 容器、调用 occ notification:generate 命令完成推送。仓库中现成的两个脚本可以帮你理解这条链路:
- Containers/nextcloud/notify.sh:向管理员发送通知。脚本先检查通知应用是否启用(
config:app:get notifications enabled),再通过occ group:list admin一次性列出管理员组成员,最后逐个调用occ notification:generate "$admin" "$NC_DOMAIN: $SUBJECT" -l "$MESSAGE" --object-type='update' --object-id="$OBJECT_ID"。其中OBJECT_ID是对主题做 SHA-256 哈希后截取前 64 字符生成的稳定标识(Nextcloud 对 object-id 长度限制为 64 字符),保证同一主题的通知可被去重/关联。 - Containers/nextcloud/notify-all.sh:向全部用户发送通知,通过
occ user:list --limit=0关闭默认 500 用户的限制来枚举所有用户。
在 PHP 侧,php/src/Docker/DockerActionManager.php 的 sendNotification(Container $container, string $subject, string $message, string $file = '/notify.sh') 方法通过 execCommandInContainer 在目标容器内执行 bash /notify.sh "$subject" "$message",其底层走 Docker Engine API 的 containers/{name}/exec 接口创建并启动 exec 实例(见同文件 execCommandInContainer)。AIO 官方容器自身的更新成功/失败、应用更新、Onlyoffice/EuroOffice/ClamAV 启动超时等场景(见 Containers/nextcloud/entrypoint.sh)均复用 bash /notify.sh 推送管理员通知,Notifications 社区容器实质上就是把这条成熟链路开放给第三方社区容器复用。
从源码结构可以推断:Notifications 容器的核心职责是代理式地完成“容器事件 → Docker socket → Nextcloud 容器内 occ 命令 → 站内通知”的调用,因此它需要
%WATCHTOWER_DOCKER_SOCKET_PATH%的只读挂载。
四、典型联动场景:Scrutiny 磁盘告警通知
文档明确给出的应用案例是 Scrutiny 容器:
- Scrutiny 是一个 SMART 统计信息的 Web 前端(镜像
ghcr.io/szaimen/aio-scrutiny,image_tag: v2),自动配置后通过http://internal.ip.of.server:8001提供磁盘仪表盘; - 该容器仅建议在家庭网络运行,且会以只读方式挂载宿主机全部
/dev与/run/udev以获得 smartctl 数据(这存在安全风险,见 scrutiny.json 中的cap_add: SYS_RAWIO, SYS_ADMIN与卷声明); - 启用 Notifications 容器后,Scrutiny 在发现 smartctl 故障时会发送管理员通知——这正是 community-containers/notifications/readme.md 中“It needs to be enabled for the scrutiny container for example to make use of admin notifications that are sent if a smartctl failure was found”所描述的场景。
换言之,Notifications 容器自身不产生告警,它扮演的是告警“投递管道”:由上游容器(如 Scrutiny)检测异常,由它把消息送达 Nextcloud 管理员。
五、如何把 Notifications 容器加入 AIO 堆栈
从 AIO v11 开始,社区容器的管理完全通过 AIO Web 界面完成(界面末尾的 “Community Containers” 区块,需向下滚动才能看到),详见 community-containers/readme.md。操作要点:
- 在 AIO 管理界面中滚动到社区容器区域,找到 “Notifications”;
- 勾选启用并启动容器,AIO 会依据
notifications.json自动完成拉取镜像、创建容器、挂载 Docker socket 与注入时区变量等步骤; - 务必先阅读各容器文档再启用——部分容器之间存在兼容性限制,未加甄别可能导致 AIO 容器启动失败;
- 若要从堆栈中移除:在 Web 界面移除后,可依次执行
sudo docker rm nextcloud-aio-notifications、sudo docker image prune -a清理不再使用的镜像,并用sudo docker volume ls检查残留卷(该容器未声明数据卷,通常无残留,此步骤为通用清理流程)。没有服务器 CLI 访问权限时,也可借助 container-management 社区容器通过 Web 会话执行 Docker 命令。
六、进阶:在自己的安装中测试新社区容器
如果你希望仿照 Notifications 的模式编写自己的社区容器,可参考 community-containers/readme.md 的本地测试流程:
- 先用标准校验器以及仓库内的 JSON Schema php/containers-schema.json 校验你的 JSON 文件;
- 在服务器某处(例如
/root)创建容器目录,如new-container; - 复制到主控容器内:
docker cp /root/new-container nextcloud-aio-mastercontainer:/var/www/docker-aio/community-containers/; - 重启主控容器:
docker restart nextcloud-aio-mastercontainer; - 打开 AIO 界面,即可看到新社区容器。
完整的 JSON 字段示例可参考 php/containers.json,Caddy、Fail2ban、Local AI、Plex 等子目录也是不错的参照模板。
七、维护信息与使用前提
- 维护者:该容器由社区维护(维护者为 szaimen,同时维护 Scrutiny 等容器)。按 community-containers/readme.md 的声明,所有社区容器均为社区维护,安全性与更新及时性由社区负责,无长期保证,生产环境启用前应自行评估。
- 镜像来源:镜像托管于 ghcr.io(GitHub Container Registry),仓库内通过 php/src/Docker/GitHubContainerRegistryManager.php 等管理器负责拉取与凭据处理。
- 使用前提:需要 Nextcloud 实例已启用通知应用(notifications app),否则
notify.sh会以 “Cannot send notification as notification app is not enabled.” 退出;通知仅发送给管理员用户(notify.sh)或全部用户(notify-all.sh),具体取决于调用方使用哪个入口。
结语
Notifications 社区容器是 AIO 生态中一个轻量而关键的“通知管道”:它以只读挂载 Docker socket 的方式,把社区容器(尤其是 Scrutiny 磁盘监控)的异常事件转化为 Nextcloud 管理员站内通知。通过 notifications.json 的逐字段解析、notify.sh 的底层实现以及 DockerActionManager.php 的调用链,你可以清晰地理解它的工作原理,并据此规划自己的社区容器告警方案。