GBHub 国标视频平台

部署文档 · v1.0

适用环境:Linux x86_64(CentOS 7 / Ubuntu 20.04+)
核心组件:gbhub-mgr、gbhub-scheduler、gbhub-sip、zlm-node、MediaServer、Valkey、GreptimeDB
部署方式:纯 Docker 命令行 + systemd

1. 前置条件

2. 统一环境变量配置(.env)

所有 gbhub 服务(mgr、scheduler、sip)共用 /usr/local/gb/.env,systemd 通过 EnvironmentFile 加载。

⚠️ 重要说明(节点上报认证机制):
zlm-node 启动后会对 NODE_TOKEN 环境变量的值进行 Blake3 哈希,然后将哈希结果通过 X-Node-Token 请求头发送给 gbhub-mgr
因此,gbhub-mgr.env 中配置的 NODE_REPORT_TOKEN 应当是原始 NODE_TOKENBlake3 哈希值,而非原始字符串。
💡 如何生成 NODE_REPORT_TOKEN:
使用 b3sum 工具计算原始 NODE_TOKEN 的 Blake3 哈希值:
# 将 your_secret_token_here 替换为实际的 NODE_TOKEN 值
echo -n "your_secret_token_here" | b3sum | awk '{print $1}'
命令拆解说明:
  • echo -n:去掉末尾换行符,确保哈希结果与代码中的计算方式完全一致。
  • b3sum:计算标准输入内容的 Blake3 哈希值。
  • awk '{print $1}':从输出中提取哈希值部分(去除文件名等额外信息)。
示例:
# 假设 NODE_TOKEN="my_secret"
echo -n "my_secret" | b3sum | awk '{print $1}'
# 输出类似:5d3f9e6c8f1a2b4c7d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c
将输出的哈希值填入下方 NODE_REPORT_TOKEN 字段。
mkdir -p /usr/local/gb
cat > /usr/local/gb/.env <<'EOF'
# ============================================================
# 国标视频平台 (gbhub) 环境配置
# ============================================================

# 数据库 (GreptimeDB / PostgreSQL)
DATABASE_URL=postgres://127.0.0.1:4003/public

# Redis 连接池配置
REDIS_URL=redis://127.0.0.1:6379?tcp_keepalive=60
REDIS_POOL_MAX_SIZE=16
REDIS_POOL_TIMEOUT_SECS=5

# SIP 信令监听地址
SERVER_LISTEN_ADDR=0.0.0.0:6060
SERVER_LISTEN_ADDR_TCP=0.0.0.0:6060

# 平台 SIP 标识
SERVER_DEVICE_ID=34020000002000000001
SERVER_REALM=3402000000
SERVER_PASSWORD=QSAe6780

# 公网 IP (用于 SIP/SDP)
PUBLIC_IP=1.1.1.1

# 管理服务器 (mgr-server) 监听地址
MGR_API_LISTEN=0.0.0.0:3002

# 信令服务器 (sip-server) HTTP 监听地址
SIP_API_LISTEN=0.0.0.0:3003

# Webhook 回调端口
HOOK_ENABLE=true
HOOK_PUBLIC_IP=127.0.0.1
HOOK_PORT=3003

# mgr-server 转发 SIP 请求的目标地址
SIP_API_BASE=http://127.0.0.1:3003

# JWT 认证
JWT_SECRET=6n5PVqybFTdWBUbpOPRvwEb6/q1PI1DhTqcmqqhenPo=
JWT_EXPIRE_DAYS=7
ADMIN_INIT_PASSWORD=admin123

# 内部服务通信(gbhub-mgr ↔ gbhub-sip)
INTERNAL_API_TOKEN=q123456778
PLAY_TOKEN=
PUBLISH_TOKEN=

# ============================================================
# 节点上报认证 Token(管理端校验用)
# 此值应为 zlm-node 中 NODE_TOKEN 原始值的 Blake3 哈希结果
# 使用命令生成:echo -n "your_secret_token" | b3sum | awk '{print $1}'
# ============================================================
NODE_REPORT_TOKEN=your_blake3_hash_here

EOF

3. 部署基础服务(Docker 容器)

3.1 导入 MediaServer 镜像

docker load -i m.tar

3.2 启动 Valkey(缓存)

docker run -d --network host --name valkey \
  -e VALKEY_EXTRA_FLAGS='--save 60 1 --loglevel warning --rdbcompression no' \
  -v /data/valkey:/data \
  valkey/valkey

3.3 启动 GreptimeDB(时序数据库)

docker run -d --network host \
  -v "/data/greptimedb_data:/greptimedb_data" \
  --name greptime \
  greptime-registry.cn-hangzhou.cr.aliyuncs.com/greptime/greptimedb:v1.1.4 \
  standalone start \
  --http-addr 127.0.0.1:4000 \
  --grpc-bind-addr 127.0.0.1:4001 \
  --mysql-addr 127.0.0.1:4002 \
  --postgres-addr 127.0.0.1:4003

3.4 部署并配置 MediaServer(ZLMediaKit)

先运行生成默认配置,再修改重启

3.4.1 准备目录和二进制

mkdir -p /data/m
mv MediaServer /data/m/

3.4.2 首次启动生成默认配置

docker run -d --network host --name me \
  -v /data/m:/app/m \
  m /app/m/MediaServer -l 4

sleep 5
docker stop me

3.4.3 修改 /data/m/config.ini

cd /data/m
sed -i 's/mediaServerId=.*/mediaServerId=1/g' config.ini
sed -i 's/port=8000/port=9100/g' config.ini
sed -i 's/tcpPort=8000/tcpPort=9100/g' config.ini
sed -i 's/externIP=.*/externIP=/g' config.ini          # 留空自动获取,也可手动指定公网IP
sed -i 's/port=80/port=9080/g' config.ini
sed -i 's/port=443/port=9443/g' config.ini
sed -i 's/secret=.*/secret=935v73f7-bb6b-4889-a715-d9eb2d1936aa/g' config.ini

3.4.4 重启容器

docker start me

3.5 部署 zlm-node(ZLM 节点上报程序)

mkdir -p /usr/local/zlm
mv zlm-node /usr/local/zlm/
chmod +x /usr/local/zlm/zlm-node

4. 部署 GB28181 核心服务

cd /usr/local
tar -xf gb.tar.gz
cd gb

获取机器码并申请授权:

./gbhub-mgr   # 打印 Machine ID,将授权文件 license.lic 放入 /usr/local/gb/
授权文件未放入前,服务启动会因 license 无效而退出。

5. 配置 systemd 服务(加载 .env)

5.1 gbhub-mgr(管理服务)

创建 /etc/systemd/system/gbhub-mgr.service

[Unit]
Description=GB28181 Management Server
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
WorkingDirectory=/usr/local/gb
EnvironmentFile=/usr/local/gb/.env
ExecStart=/usr/local/gb/gbhub-mgr
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=gbhub-mgr

[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now gbhub-mgr.service

5.2 gbhub-scheduler(调度服务)

创建 /etc/systemd/system/gbhub-scheduler.service(内容类似,ExecStart 改为 gbhub-schedulerEnvironment="RUST_LOG=warn" 可加在 [Service] 段),然后启动。

5.3 gbhub-sip(SIP 信令服务)

创建 /etc/systemd/system/gbhub-sip.service(内容类似,ExecStart 改为 gbhub-sip),然后启动。

5.4 zlm-node(ZLM 节点上报程序)

创建 /etc/systemd/system/zlm-node.service,所有环境变量名均与 Rust 代码中的 Config 结构体字段对应(大写)。

⚠️ 认证机制说明:
程序启动后会读取 NODE_TOKEN 的原始字符串值,计算其 Blake3 哈希,然后将哈希值放入请求头 X-Node-Token 中上报。
因此,请务必保证 NODE_TOKEN 的原始值,与 /usr/local/gb/.envNODE_REPORT_TOKEN 的哈希值相匹配。
[Unit]
Description=zlm-node (ZLM Node Reporter)
After=network.target

[Service]
Type=simple
EnvironmentFile=/usr/local/gb/.env

# ---------- 日志级别 ----------
Environment="RUST_LOG=warn"

# ---------- 必填:节点上报原始认证令牌 ----------
# 此值为原始字符串(明文),程序内部会计算 Blake3 哈希后发送
# 务必与 .env 中 NODE_REPORT_TOKEN 的哈希值匹配
Environment="NODE_TOKEN=your_secret_token_here"

# ---------- 节点标识(必须与 MediaServer 的 mediaServerId 一致) ----------
Environment="SERVER_ID=1"

# ---------- ZLM API 地址及密钥 ----------
Environment="API_BASE=http://127.0.0.1:9080"
Environment="SECRET=935v73f7-bb6b-4889-a715-d9eb2d1936aa"

# ---------- 管理端上报接口 ----------
Environment="MGR_URL=http://127.0.0.1:3002/api/zlm/report-status"

# ---------- IP 获取策略(优先级:CUSTOM_IP > INTERFACE > 外网API) ----------
# 1. 手动指定公网 IP(取消注释并填写实际IP)
# Environment="CUSTOM_IP=1.1.1.1"
# 2. 指定网卡名称(如 eth0)
# Environment="INTERFACE=eth0"
# 3. 以上均不设置,则自动通过外网API获取(ip.3322.net / ip.automate.org.cn)

# ---------- 播放地址构造参数 ----------
Environment="ZLM_HTTP_PORT=9080"
Environment="USE_HTTPS=false"

# ---------- 可选:手动指定 http_fmp4_base 或 static_base ----------
# Environment="HTTP_FMP4_BASE=https://custom-domain.com:9443/"
# Environment="STATIC_BASE=http://cdn.example.com/"

# ---------- 上报间隔(秒) ----------
Environment="REPORT_INTERVAL_SECS=30"

# ---------- 是否自动更新 ZLM 的 rtc.externIP(默认 true) ----------
Environment="ENABLE_RTC_EXTERN_IP_UPDATE=true"

# ---------- 是否接受无效 TLS 证书(自签名场景) ----------
# Environment="TLS_ACCEPT_INVALID_CERTS=false"

ExecStart=/usr/local/zlm/zlm-node
Restart=always
PrivateTmp=true

[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now zlm-node.service

6. 验证服务状态

systemctl status gbhub-mgr gbhub-scheduler gbhub-sip zlm-node
docker ps | grep -E "valkey|greptime|me"

查看 zlm-node 日志(观察上报及 IP 获取情况):

journalctl -u zlm-node -f

7. 防火墙与端口开放(iptables / nftables)

需开放以下端口(根据实际访问需求调整):

服务端口协议说明
gbhub-sip (SIP)6060UDP/TCPSIP 信令
MediaServer (HTTP API)9080TCPZLM HTTP API / Web 页面
MediaServer (HTTPS API)9443TCPZLM HTTPS API / Web 页面
MediaServer (RTP 控制)9100TCPRTP 控制端口
MediaServer (RTP 媒体流)30000-35000UDP/TCPRTP 媒体传输端口范围
gbhub-mgr API3002TCP管理后台 API
gbhub-sip HTTP API3003TCPSIP HTTP 接口 / Webhook
数据库(6379、4000-4003)和 Valkey 端口建议仅监听本地,不对外暴露。

7.1 使用 iptables(CentOS 7 / 传统系统)

# 开放 SIP 信令
iptables -A INPUT -p udp --dport 6060 -j ACCEPT
iptables -A INPUT -p tcp --dport 6060 -j ACCEPT

# 开放 MediaServer API
iptables -A INPUT -p tcp --dport 9080 -j ACCEPT
iptables -A INPUT -p tcp --dport 9443 -j ACCEPT

# 开放 RTP 控制端口
iptables -A INPUT -p tcp --dport 9100 -j ACCEPT

# 开放 RTP 媒体流端口范围(UDP 和 TCP)
iptables -A INPUT -p udp --dport 30000:35000 -j ACCEPT
iptables -A INPUT -p tcp --dport 30000:35000 -j ACCEPT

# 开放管理 API
iptables -A INPUT -p tcp --dport 3002 -j ACCEPT
iptables -A INPUT -p tcp --dport 3003 -j ACCEPT

# 保存规则(CentOS 7)
service iptables save
# 或 iptables-save > /etc/sysconfig/iptables

7.2 使用 nftables(Ubuntu 20.04+ / 现代发行版)

# 添加规则(临时生效)
nft add rule inet filter input udp dport 6060 accept
nft add rule inet filter input tcp dport 6060 accept
nft add rule inet filter input tcp dport 9080 accept
nft add rule inet filter input tcp dport 9443 accept
nft add rule inet filter input tcp dport 9100 accept
nft add rule inet filter input udp dport 30000-35000 accept
nft add rule inet filter input tcp dport 30000-35000 accept
nft add rule inet filter input tcp dport 3002 accept
nft add rule inet filter input tcp dport 3003 accept

# 持久化保存(Ubuntu)
nft list ruleset > /etc/nftables.conf
systemctl enable nftables
若在云平台(如阿里云、腾讯云、AWS)部署,还需在安全组/防火墙策略中放行相应端口。

8. 常见问题及解决

9. 卸载清理

systemctl stop gbhub-mgr gbhub-scheduler gbhub-sip zlm-node
systemctl disable gbhub-mgr gbhub-scheduler gbhub-sip zlm-node
rm -f /etc/systemd/system/gbhub-*.service /etc/systemd/system/zlm-node.service
docker rm -f valkey greptime me
rm -rf /usr/local/gb /usr/local/zlm /data/valkey /data/greptimedb_data /data/m
docker rmi m valkey/valkey greptime-registry.cn-hangzhou.cr.aliyuncs.com/greptime/greptimedb:v1.1.4

10. 环境变量速查表(zlm-node)

变量名说明必填默认值
NODE_TOKEN上报原始令牌(明文,程序内部会计算 Blake3 哈希后发送)
NODE_REPORT_TOKEN管理端 .env 中配置的预期哈希值(应为 NODE_TOKEN 的 Blake3 结果)是(在 .env 中)
SERVER_ID节点 ID(与 mediaServerId 一致)"1"
API_BASEZLM HTTP API 地址http://127.0.0.1:9080
SECRETZLM API 密钥935v73f7-bb6b-4889-a715-d9eb2d1936aa
MGR_URL管理端上报接口http://127.0.0.1:3002/api/zlm/report-status
CUSTOM_IP手动指定公网 IP(最高优先级)自动获取
INTERFACE指定网卡名称
ZLM_HTTP_PORTZLM HTTP 端口(拼接 URL)9080
USE_HTTPS是否使用 HTTPS 构造播放地址false
HTTP_FMP4_BASE手动指定 http_fmp4_base自动生成
STATIC_BASE手动指定静态资源基地址与 http_fmp4_base 相同
REPORT_INTERVAL_SECS上报间隔(秒)30
ENABLE_RTC_EXTERN_IP_UPDATE自动更新 ZLM 的 rtc.externIPtrue
TLS_ACCEPT_INVALID_CERTS接受无效 TLS 证书false
RUST_LOG日志级别(info/warn/debug)程序默认 info