Nightingale 9.2.0 Docker Compose 部署指南
Nightingale(夜莺)v9.2.0 Docker Compose 端到端实测部署:n9e+MySQL+Redis+VictoriaMetrics+Categraf 五角色栈编排、镜像构建、数据持久化、登录认证、采集入库、告警规则触发与 Webhook 通知触达全链路验证,附真实排障实录
Nightingale 9.2.0 Docker Compose 部署指南
目标:在一台 Linux 服务器上用 Docker Compose 从 0 到 1 拉起一套可用的 Nightingale(夜莺)v9.2.0 监控告警栈,覆盖 n9e 服务端、MySQL、Redis、VictoriaMetrics 与 Categraf 采集器五个角色,并完成「登录认证 → 采集入库 → 告警规则 → 事件 → Webhook 通知触达」的端到端验证。全文命令与输出均为真实服务器实测回显。
一、环境信息
| 项目 | 值 | 说明 |
|---|---|---|
| 服务器操作系统 | Linux,内核 6.8.0-138-generic | Ubuntu 系宿主机,已安装 Docker |
| Docker / Compose | Docker version 29.8.1 / Docker Compose version v5.5.1 | docker --version 与 docker compose version 实测 |
| 服务端版本 | v9.2.0-01a8e22eb21d81f5cbe5c34e5a1511ff63e39983 | n9e --version 实测输出 |
| 采集器版本 | v0.5.15-3232630235e3602477778a4df6c6eb7d99839f7a | categraf --version 实测输出 |
| 时序数据库 | VictoriaMetrics v1.153.0(单机版) | 官方镜像 victoriametrics/victoria-metrics:v1.153.0 |
| 元数据库 | MySQL 8.0 | 官方镜像 mysql:8.0 |
| 缓存 | Redis 7.2 | 官方镜像 redis:7.2 |
| 端口规划 | 宿主 8130 → n9e Web 17000;宿主 8131 → VictoriaMetrics 8428 | MySQL/Redis 仅容器网内访问,不对外映射 |
| Compose 项目名 | nightingale-9-2-0-stack | compose 顶层 name 显式声明,保证容器/网络前缀可辨识 |
| 专用网络 | 桥接网段 10.89.60.0/24 | 部署前用 docker network inspect 确认该网段未被占用 |
二、版本与镜像选型说明
Nightingale 官方发布物有两条获取路径,实测选择如下:
- 官方 Docker Hub 镜像:
flashcatcloud/nightingale:latest(官方 Dockerfile 基于python:3-slim,镜像内含/app/n9e、/app/etc、/app/integrations与捆绑的 categraf 压缩包)。实测直连与多个镜像加速源拉取该镜像时均在中途传输层报EOF(约百 MB 级的 agents 层在受限网络下中断):failed to copy: httpReadSeeker: failed open: failed to read all: received unexpected EOF - 官方 Release 二进制自建镜像:从 GitHub Releases 下载
n9e-v9.2.0-linux-amd64.tar.gz(内含n9e二进制、etc/默认配置、integrations/集成包)与categraf-v0.5.15-linux-amd64.tar.gz,基于ubuntu:22.04构建本地镜像nightingale-9-2-0:local(474MB)与categraf-0-5-15:local(399MB)。
本文以路径 2 为主线(版本号精确、可复现),路径 1 在网络可达时可直接替换 image: 字段使用,其余步骤完全一致。
💡 说明:Nightingale 服务端是 Go 编译的单二进制,镜像仅提供运行环境,因此自建镜像与官方镜像在功能上等价;官方镜像额外内置的
integrations集成说明包本文同样保留进镜像。
三、目录结构与构建镜像
3.1 目录结构
/opt/data/quzuo/tmp/nightingale/compose/
├── docker-compose.yml # 编排文件(下文给出全文)
├── Dockerfile.n9e # n9e 镜像构建文件
├── Dockerfile.categraf # categraf 镜像构建文件
├── etc-nightingale/config.toml # n9e 主配置(由 Release 包 etc/config.toml 演化)
├── initsql/ # MySQL 初始化 SQL(来自 Release 包)
├── etc-categraf/ # categraf 配置(config.toml + input.* 插件配置)
├── mysqldata/ # MySQL 数据目录(卷挂载)
└── vmdata/ # VictoriaMetrics 数据目录(卷挂载)
初始化 SQL 说明:Release 包内 docker/initsql/ 提供两个文件,a-n9e.sql 创建 n9e_v6 库与全部表并写入默认 root 用户(初始口令 root.2020),c-init.sql 允许 root 从任意主机连接(按需把口令从默认 1234 改为自己的值,本文统一用测试口令 q1w2e3r4)。
3.2 镜像构建文件
Dockerfile.n9e:
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates tzdata && rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY n9e /app/n9e
COPY etc /app/etc
COPY integrations /app/integrations
EXPOSE 17000
CMD ["/app/n9e"]
Dockerfile.categraf:
FROM ubuntu:22.04
WORKDIR /opt/categraf
COPY categraf /opt/categraf/categraf
COPY etc-categraf /etc/categraf/conf
CMD ["/opt/categraf/categraf"]
构建(工作目录 compose/):
docker build -f Dockerfile.n9e -t nightingale-9-2-0:local build/n9e
docker build -f Dockerfile.categraf -t categraf-0-5-15:local build/categraf
构建完成后 docker images 确认:
nightingale-9-2-0 local 474MB
categraf-0-5-15 local 399MB
四、docker-compose.yml 全文
name: nightingale-9-2-0-stack
networks:
nightingale:
name: nightingale-9-2-0-net
driver: bridge
ipam:
config:
- subnet: 10.89.60.0/24
services:
mysql:
image: mysql:8.0
container_name: nightingale-9-2-0-mysql
hostname: mysql
restart: always
environment:
TZ: Asia/Shanghai
MYSQL_ROOT_PASSWORD: q1w2e3r4
volumes:
- ./mysqldata:/var/lib/mysql
- ./initsql:/docker-entrypoint-initdb.d
networks:
- nightingale
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-pq1w2e3r4"]
interval: 5s
timeout: 5s
retries: 30
redis:
image: redis:7.2
container_name: nightingale-9-2-0-redis
hostname: redis
restart: always
environment:
TZ: Asia/Shanghai
networks:
- nightingale
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 5s
retries: 30
victoriametrics:
image: victoriametrics/victoria-metrics:v1.153.0
container_name: nightingale-9-2-0-vm
hostname: victoriametrics
restart: always
environment:
TZ: Asia/Shanghai
volumes:
- ./vmdata:/victoria-metrics-data
ports:
- "8131:8428"
networks:
- nightingale
command:
- "--loggerTimezone=Asia/Shanghai"
- "--retentionPeriod=100y"
healthcheck:
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:8428/health"]
interval: 5s
timeout: 5s
retries: 30
nightingale:
image: nightingale-9-2-0:local
container_name: nightingale-9-2-0-n9e
hostname: nightingale
restart: always
environment:
GIN_MODE: release
TZ: Asia/Shanghai
volumes:
- ./etc-nightingale:/app/etc
ports:
- "8130:17000"
networks:
- nightingale
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
victoriametrics:
condition: service_healthy
command:
- /app/n9e
categraf:
image: categraf-0-5-15:local
container_name: nightingale-9-2-0-categraf
hostname: categraf01
restart: always
environment:
TZ: Asia/Shanghai
HOST_PROC: /hostfs/proc
HOST_SYS: /hostfs/sys
HOST_MOUNT_PREFIX: /hostfs
volumes:
- ./etc-categraf:/opt/categraf/conf
- /:/hostfs:ro
networks:
- nightingale
depends_on:
- nightingale
要点说明:
name: nightingale-9-2-0-stack:显式项目名,docker compose ps、网络名、默认卷前缀都以此为前缀,便于多套栈并存时辨识。restart: always+ 各依赖healthcheck:保证宿主机重启后整套栈自愈,且 n9e 严格在 MySQL/Redis/VM 就绪后才启动。- MySQL/Redis 不映射宿主端口:仅容器网内互通,减少攻击面;VictoriaMetrics 的
8428与 n9e 的17000按需映射到宿主8131/8130。 - categraf 挂载宿主根目录
/到只读/hostfs,配合HOST_PROC/HOST_SYS/HOST_MOUNT_PREFIX采集宿主机指标(进程、磁盘、网络等)。
五、部署步骤
5.1 启动
cd /opt/data/quzuo/tmp/nightingale/compose
docker compose up -d
首次启动 MySQL 会执行 initsql 中的建库脚本(约半分钟),随后 n9e 完成初始化。启动完成后查看状态:
$ docker ps --filter name=nightingale --format 'table {{.Names}}\t{{.Status}}'
NAME STATUS
nightingale-9-2-0-categraf Up
nightingale-9-2-0-n9e Up
nightingale-9-2-0-mysql Up 17 minutes (healthy)
nightingale-9-2-0-redis Up 17 minutes (healthy)
nightingale-9-2-0-vm Up 17 minutes (healthy)
n9e 启动日志(docker logs nightingale-9-2-0-n9e | head)关键行:
I! n9e version: v9.2.0-01a8e22eb21d81f5cbe5c34e5a1511ff63e39983, build time: 2026-10-11 15:48:08
I! warning: not using a default config file, using mysql as the database
root password init done
http server listening on: [::]:17000
I! username/password: root/root.2020
5.2 配置文件要点(etc-nightingale/config.toml)
默认配置只需改三处即可运行:
[Log]
Level = "INFO"
[HTTP]
Host = "0.0.0.0"
Port = 17000
[DB]
DSN = "root:q1w2e3r4@tcp(mysql:3306)/n9e_v6?charset=utf8mb4&parseTime=True&loc=Local&allowNativePasswords=true"
[Redis]
Address = "redis:6379"
[[Pushgw.Writers]]
Url = "http://victoriametrics:8428/api/v1/write"
DB.DSN指向 compose 网络内的mysql服务;Redis.Address指向redis服务;Pushgw.Writers让 n9e 把收到的监控数据转发写入 VictoriaMetrics(Categraf → n9e → VM 的数据面)。
5.3 数据持久化与升级
- MySQL 数据落
./mysqldata,VictoriaMetrics 数据落./vmdata,均为 bind mount,docker compose down不会丢数据;down -v也只清理命名卷,bind mount 数据仍在目录中。 - 升级 n9e:下载新版 Release 包替换
build/n9e/n9e二进制,重建镜像后docker compose up -d nightingale;MySQL 表结构由 n9e 启动时自动迁移。
六、登录验证与初始安全配置
6.1 Web 登录
浏览器访问 http://<服务器IP>:8130,默认账号 root,初始口令 root.2020(见启动日志)。登录后立即修改口令,本文统一改为测试口令 q1w2e3r4。
6.2 API 登录取证
curl -s -X POST 'http://127.0.0.1:8130/api/n9e/auth/login' \
-H 'Content-Type: application/json' \
-d '{"username":"root","password":"root.2020"}'
实测回显(JWT 截断显示):
{"err":"","dat":{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NfdXVpZCI6IjMzZjBjZjVjLWQyYTUtNDFiNi05YzY5LTM2YjY5MzM1MmYwNiJ9....","refresh_token":"...","user":{"id":1,"username":"root","role":"Admin"}}}
修改口令(携带登录返回的 Authorization: Bearer <token>):
curl -s -X PUT 'http://127.0.0.1:8130/api/n9e/self/password' \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"oldpass":"root.2020","newpass":"q1w2e3r4"}'
实测回显:{"err":"","request_id":"31a7dcb6-6b60-4951-b163-6cd02576c6e1"}。用新口令重新登录成功即完成初始安全配置。
七、端到端全链路验证
以下六步依次验证「采集 → 入库 → 告警 → 通知」完整闭环,全部为实测命令与回显。
7.1 注册 VictoriaMetrics 数据源
Web「数据源管理」或 API 注册 Prometheus 类型数据源(API 示例,关键字段 cluster_name 见 7.6 排障):
curl -s -X POST 'http://127.0.0.1:8130/api/n9e/datasource/upsert' \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"name":"victoria-metrics","identifier":"vm-01","plugin_type":"prometheus","plugin_type_name":"Prometheus Like","category":"timeseries","cluster_name":"default","settings":{},"http":{"url":"http://victoriametrics:8428","urls":["http://victoriametrics:8428"],"timeout":10000,"dial_timeout":3000,"tls":{},"max_idle_conns_per_host":100,"headers":{}},"auth":{"basic_auth":false,"basic_auth_user":"","basic_auth_password":""},"is_default":true,"weight":100}'
实测回显:{"err":"","dat":{"verification":"verified","id":1}}——verified 表示连通性测试通过。
7.2 确认采集器心跳注册
curl -s 'http://127.0.0.1:8130/api/n9e/targets?gids=0' -H "Authorization: Bearer $TOKEN"
实测回显(截断):categraf01 已自动注册,agent_version: v0.5.15,target_up: 2(进程/插件存活状态)。
7.3 指标入库(Categraf → n9e → VictoriaMetrics)
curl -s 'http://127.0.0.1:8131/api/v1/label/__name__/values' | python3 -m json.tool | head
实测回显:
446 个指标名,包括 cpu_usage_active、mem_available_percent、system_load1、disk_used_percent 等
即时查询验证数值有效:
$ curl -s 'http://127.0.0.1:8131/api/v1/query?query=mem_available_percent'
{"status":"success","data":{"resultType":"vector","result":[{"metric":{"__name__":"mem_available_percent","agent_hostname":"categraf01","ident":"categraf01"},"value":[1792470782,"75.82"]}]}}
7.4 创建告警规则
在默认业务组(busi-group/1)创建阈值规则「内存使用率超过 20%」(100 - mem_available_percent > 20,当前约 24%,必然触发):
curl -s -X POST 'http://127.0.0.1:8130/api/n9e/busi-group/1/alert-rules' \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '[{"name":"memory-usage-over-20-percent","note":"mem usage > 20%","cate":"prometheus","prod":"metric","datasource_queries":[{"match_type":0,"op":"in","values":[1]}],"severity":2,"disabled":0,"rule_config":{"queries":[{"prom_ql":"100 - mem_available_percent","severity":2,"unit":"percent"}]},"prom_eval_interval":15,"prom_for_duration":0,"notify_recovered":1,"notify_channels":[],"notify_groups":[],"notify_repeat_step":60,"recover_duration":60,"callbacks":["http://10.89.60.1:18080/hook"],"enable_days_of_weeks":[["1","2","3","4","5","6","0"]],"enable_stimes":["00:00"],"enable_etimes":["23:59"],"annotations":{},"append_tags":[]}]'
实测回显:{"err":"","dat":[1]}(规则 id=1)。
7.5 告警事件触发
等待一个评估周期(15 秒),查询当前事件:
$ curl -s 'http://127.0.0.1:8130/api/n9e/alert-cur-events/list?limit=5&p=1' -H "Authorization: Bearer $TOKEN"
total: 1
rule=memory-usage-over-20-percent-v2 severity=2
tags: ['ident=categraf01', 'rulename=memory-usage-over-20-percent-v2']
同时 n9e 日志可见评估触达明细:
INFO dispatch/log.go:20 alert_eval_1 event(...) triggered: cluster:victoria-metrics
[ident=categraf01 rulename=memory-usage-over-20-percent-v2] 27.66% @1792471221
7.6 Webhook 通知触达
规则 callbacks 配置了 http://10.89.60.1:18080/hook(宿主机上的一个 HTTP 接收器),事件触发后 n9e 以 POST JSON 回调,接收端实测收到完整事件体(节选):
{"rule_name":"memory-usage-over-20-percent-v2","trigger_value":"27.66%",
"tags":["ident=categraf01","rulename=memory-usage-over-20-percent-v2"],
"cluster":"victoria-metrics","notify_channels":["email"],"cate":"prometheus",...}
至此「采集 → 入库 → 规则评估 → 事件 → 通知触达」六环节全部验证通过。
八、等价单容器运行验证(docker run)
不使用 Compose 时,上述 n9e 服务可用 docker run 等价拉起(接入同一 nightingale-9-2-0-net 网络,宿主端口换用 8133 避免冲突):
docker run -d --rm --name nightingale-9-2-0-runtest \
--network nightingale-9-2-0-net -p 8133:17000 \
-e TZ=Asia/Shanghai \
-v /opt/data/quzuo/tmp/nightingale/compose/etc-nightingale:/app/etc \
nightingale-9-2-0:local /app/n9e
实测验证登录接口正常返回 JWT 后移除测试容器:docker rm -f nightingale-9-2-0-runtest。该路径证明了镜像本身可独立运行,Compose 编排只是把「依赖顺序 + 网络互联 + 数据持久化」固化为声明式配置。
九、常见问题与排障实录
以下问题均在本次部署实测中真实遇到,按「现象 → 定位 → 解决」记录。
- categraf 容器反复重启(Restarting):日志报
open conf/config.toml: no such file or directory。categraf 二进制默认在工作目录相对路径conf/下找配置,官方镜像通过内部约定解决;自建镜像需把配置挂载到/opt/categraf/conf(即工作目录下的conf),或启动参数显式--configs=/etc/categraf/conf。 - 告警规则创建后永不触发(事件数恒为 0):这是 v9 部署最易踩的坑。定位过程——引擎心跳表
alerting_engines中只有datasource_id=0(全局)与99999999(特殊)两行,没有数据源 1 的心跳行;源码models/alert_rule.go显示引擎只为cluster_name等于引擎集群名(默认default)的数据源注册心跳哈希环,而通过 API 创建的数据源若不传cluster_name则为空,规则被分片评估时永远未命中。解决:更新数据源补cluster_name:"default",心跳行出现后 15 秒内事件即触发。 - 删除事件后不重新通知:n9e 按
notify_repeat_step(分钟)对同一事件哈希做通知节流,日志可见stalled, notify_repeat_step_not_matched;恢复通知需等待节流窗口结束或产生新哈希的事件。 - categraf 的 mysql 监控插件报
Access denied for user 'root'@'10.89.60.6':input.mysql/mysql.toml中口令与本机 MySQL 实际口令不一致所致,按实际值修改即可;不需要该插件时直接删除input.mysql目录。 - 官方镜像拉取失败:受限网络下 Docker Hub 大层传输易中断(
received unexpected EOF),可改用 GitHub Release 二进制自建镜像(本文主线),或走可信的镜像加速源。
十、参考链接
- 官方部署文档:https://n9e.docs.io (快猫星云文档中心)
- GitHub 仓库:https://github.com/ccfos/nightingale
- Categraf 仓库:https://github.com/flashcatcloud/categraf
- 本专栏相关:《Nightingale 9.2.0 介绍与选型指南》(架构与选型)、《Nightingale 9.2.0 配置参数详解》(config.toml 逐段说明)、《Nightingale 9.2.0 常用 CLI 命令详解》(n9e/categraf 命令行)