自托管部署
最小可用拓扑、LiveKit 与 Egress、环境变量清单、健康与就绪探针、备份与升级步骤。
版本 v1.1.0 · 更新于 2026-10-26 · 修订 1
自托管是 ni-meet 与「直接用别人的云」最大的区别:整套东西都跑在你自己的机器/集群上。这一页给出三种部署形态、环境变量、健康检查、备份与升级,以及对生产环境的硬要求。
三种形态#
| 形态 | 命令 | 媒体面 | 录制 | 用途 |
| 本地开发 | pnpm dev:api | memory 模拟器 | 进程内模拟调度 | 零依赖做业务、跑测试、跑文档示例 |
| 本地真实 SFU | docker compose -f deploy/compose.yml up livekit redis api(NIMEET_SFU_ADAPTER=livekit) | 真实 LiveKit | LiveKit Egress | 验证真实媒体链路 |
| 全栈 | docker compose -f deploy/compose.yml up | LiveKit + TURN | 独立 egress 容器 + egress-worker | 生产同构,含隔离与压测 |
bashdocker compose -f deploy/compose.yml up -d --build
首次启动 API 会把一次性演示凭证写到 data/demo-credentials.json。暴露到公网前必须改掉 CONSOLE_SEED_PASSWORD、NIMEET_WEBHOOK_SIM_SECRET、NIMEET_EGRESS_WORKER_TOKEN。
环境变量(只列会影响功能的)#
| 变量 | 默认值 | 含义 |
PORT / HOST | 8787 / 0.0.0.0 | API 监听 |
NIMEET_SFU_ADAPTER | memory | memory(模拟)或 livekit |
LIVEKIT_HOST / LIVEKIT_API_KEY / LIVEKIT_API_SECRET | — | livekit 适配必填 |
NIMEET_EGRESS_MODE | local | remote 时把任务派给 worker 进程 |
NIMEET_EGRESS_WORKERS | — | worker URL 列表(逗号分隔) |
NIMEET_EGRESS_WORKER_TOKEN | — | worker 控制面的 bearer token |
EGRESS_MAX_CONCURRENT / EGRESS_QUEUE_LIMIT | 8 / 200 | 控制面并发闸门与队列 |
EGRESS_NODE_COUNT / EGRESS_NODE_CAPACITY | 2 / 4 | 本地节点池形状 |
NIMEET_SEED_DEMO | true | 是否 seed 演示项目与分析数据(生产设 false) |
RECORDING_STORAGE_VENDOR | local | s3 / oss / cos / gcs / local |
RTMP_PUSH_BASE / HLS_PLAY_BASE | 示例域名 | 推流/播放地址模板 |
WORKER_CAPACITY / WORKER_QUEUE_LIMIT / WORKER_MAX_JOB_MS | 2 / 100 / 4h | egress worker 限制 |
NIMEET_RATE_LIMIT_PER_MINUTE / _BURST | 600 / 60 | 请求限流(见 配额) |
PUBLIC_BASE_URL | — | 对外访问地址;回调链接、分享链接用它拼绝对 URL |
VITE_SFU_URL(前端构建/启动时) | — | 浏览器要连的媒体地址(本地 wss://sfu.your-domain.example,生产 wss://sfu.your-domain.example)。Token 里没有 SFU 地址字段:前端只有两条来源——构建时的这个变量,或 IM Provider 返回的 serverUrl |
健康与就绪#
| 端点 | 用途 |
GET /healthz | 存活探针(进程还在) |
GET /readyz | 就绪探针(存储与 SFU 可用) |
GET /metrics | Prometheus 指标(运维使用,不要暴露到公网) |
Kubernetes 里把健康检查端点设为 liveness/readiness;调度器与 worker 的管理端口只在集群内网暴露。
网络与入口#
- 公网反向代理只暴露:
/v1/*、/dev/v1/*、/console/*;管理端口仅限集群内网; - 必须允许 WebSocket 升级(
/rtc 反代到 LiveKit),否则客户端会一直重连; - TURN:compose 里 LiveKit 自带 TURN,需放通
3478/udp 与 5349/tcp; - LiveKit webhook 只需配置一次(
deploy/livekit.yaml),API 从房间名 <appId>:<channel> 反推项目并验签。
生产硬要求(不满足别上线)#
| 项 | 要求 | 原因 |
| 存储 | 接入 Postgres 等持久化存储 | 内存存储是单进程假设,重启即丢 |
| 录制隔离 | egress-worker 与 SFU 分开机器/CPU 池 | 录制是 CPU 密集型,会抢占媒体面 |
| 容量 | 按 docs/performance/egress-stress.md 的实测数字定 WORKER_CAPACITY | 拍脑袋会导致任务排队超时 |
| 密钥 | 全部走密钥管理,不进镜像 | appCertificate 泄露 = 所有 Token 可伪造 |
| 备份 | 每日备份业务库 + 对象存储生命周期策略 | 录制文件是客户资产 |
升级步骤#
- 先升级 API(向后兼容一个版本),观察
readyz 与错误率; - 再升级 egress worker:排空(停止接新任务)→ 等在跑的任务结束 → 替换;
- 最后升级 LiveKit / Egress(媒体面版本变更会影响推流与录制编码);
- 升级后在文档示例目录运行
node examples/run-all.mjs --all 做回归验证。
备份与恢复#
| 数据 | 位置 | 备份方式 |
| 项目/频道/任务/用量 | 业务库 | 数据库快照 + PITR |
| 录制文件 | RECORDING_STORAGE_VENDOR 指向的对象存储 | 桶版本化 + 跨区复制 |
| 驱动日志 | 进程 stdout / 日志系统 | 保留 ≥ 7 天,按 X-Request-Id 检索 |
常见部署问题#
| 现象 | 原因 | 处理 |
| 客户端一直 RECONNECTING | 反代没放行 WebSocket | 开启 Upgrade/Connection 头透传 |
| 录制任务一直排队 | EGRESS_MAX_CONCURRENT 太小或 worker 异常 | 检查 Egress 节点容量与任务队列 |
| 录制文件 404 | 存储 vendor 配置与桶权限不一致 | 用 文档与接口定义自动化校验 自检 |
| 回调收不到 | webhook 未配置/secret 不一致 | 控制台配置后看投递日志 |
| 重启后数据全丢 | 用了内存存储 | 换 Postgres 实现 |