CyTube 常用命令与运维实战(核心篇)

CyTube 3.86.1 运维核心实战:bin/admin.js 三命令(ban-channel/show-banned-channel/unban-channel)逐条实测回显、servcmd.sh.js 交互通道与失效命令/上游笔误踩坑、频道加载卸载与强制保存日志指纹、MariaDB 全库备份与删库重建恢复演练(14 表全核对)、四文件日志排障口诀、升级流程与三条经验、八类故障速查表。

CyTubeCyTube流媒体自托管2026/10/29

CyTube 常用命令与运维实战(核心篇)

目标:把 CyTube 3.86.1 的日常运维做扎实——站点管理命令(bin/admin.js servcmd 全家桶)逐命令实测、频道管理联动回显、MariaDB 备份与恢复全流程演练(含删库重建)、四文件日志体系排障用法、版本升级流程。全部命令与回显逐行照抄自真实运维现场。前置认知与部署过程见《CyTube 介绍与选型指南》与《CyTube Docker Compose 部署实战》,配置参数细节见《CyTube 配置参数详解》。

一、运维体系总览

CyTube 的运维操作有三条通道,按场景选用:

通道入口适用场景
站点管理后台 ACP站点管理员登录后访问 /acp界面化查看频道列表、全局封禁、系统开关
管理命令行 servcmd应用目录下 bin/admin.js 与交互通道 servcmd.sh.js脚本化封禁/解封频道、stdin 不可用场景下的管理入口
数据库直连MariaDB 客户端数据订正(如提权)、备份恢复、问题取证

三条通道的权限锚点一致:users 表 global_rank >= 255 的账号。本文以命令行通道为主——它是自动化运维(定时巡检、批量处置)的基石。

💡 技术拓展:servcmd 的底层是 UNIX 套接字 service.sock(由配置段 service-socket.enabled: true 开启,应用启动日志 main: Opening service socket 即它在工作)。应用把一个命令处理循环同时接到两个入口:套接字与进程 stdin——所以直接在应用控制台敲 /reload 与从套接字发 /reload 等价。这正是官方注释里"PM2 等 stdin 不可用场景"的解法。

二、servcmd 管理命令实测

2.1 命令清单

在应用运行目录执行 node bin/admin.js(不带子命令),实测回显:

No log backend bound for jsli.  Logging to stdout.
[WARN] config: Detected 127.0.0.1 or localhost in root-domain 'localhost'.  ...
[WARN] config: socket.io is bound to localhost, ...
[WARN] config: No YouTube v3 API key set.  ...
[WARN] config: No Twitch Client ID set.  ...
[INFO] config: Loaded configuration from config.yaml
[INFO] config: No camo configuration found, chat images will not be proxied.
[INFO] config: Loaded prometheus configuration from conf/prometheus.toml.  Prometheus listener is ENABLED
[INFO] config: No email configuration found, defaulting to disabled
[INFO] config: No captcha configuration found, defaulting to disabled
Available commands:
  * ban-channel
  * unban-channel
  * show-banned-channel

3.86.1 的正式命令就这三个(封禁频道、解封频道、查询封禁状态)。前导的 WARN/INFO 是命令行加载配置的自检输出——bin/admin.js 与主应用读同一份 config.yaml,因此它也是配置体检工具(四条 WARN 的含义见《CyTube 配置参数详解》第一节)。

2.2 封禁频道:ban-channel

用法 ban-channel <频道名> <对外原因> <内部原因>,命令行会先回显操作摘要并要求输入 y 确认(防手滑)。实测封禁演示频道 movie-night:

printf 'y\n' | node bin/admin.js ban-channel movie-night '违反社区公约:演示封禁' '运维篇实测演示'

实测回显:

Ban movie-night with external reason "违反社区公约:演示封禁" and internal reason "运维篇实测演示"? Ban succeeded.

Ban succeeded. 落地的证据有三处,逐处验证:

  1. 数据库落表:
mariadb -ucytube3 -pq1w2e3r4 cytube3 -e 'select id, name, external_reason, banned_by from banned_channels;'

实测回显:

id	name	external_reason	banned_by
1	movie-night	违反社区公约:演示封禁	[console]
  1. 应用事件日志(events.log 尾部,实测):
[Wed Oct 28 2026 15:49:22] [acp] [console] banned channel movie-night
  1. 在线用户被实时踢出:封禁后任何加入尝试都会被拒,主日志实测回显(观众 socket 刚连上就收踢):
[INFO] user: 10.89.60.1 (admin) was kicked: "Channel could not be loaded: Channel is banned: 测试封禁:运维篇演示"

💡 技术拓展:[console] 是命令行通道的操作者标识;若从 ACP 界面执行同样操作,这里会显示管理员账号名。external_reason(对外原因)会在观众被踢时展示,internal_reason(内部原因)只进审计记录——封禁话术要区分"能给人看的"与"留给管理员查的"。

2.3 查询封禁状态:show-banned-channel

node bin/admin.js show-banned-channel movie-night

实测回显(封禁中,完整审计信息):

Channel: movie-night
Ban issued: 2026-10-28T16:00:45.000Z
Banned by: [console]
External reason:
违反社区公约:演示封禁
Internal reason:
运维篇实测演示

未封禁频道的查询回显:

Channel movie-night is not banned.

这条命令适合放进定时巡检脚本:拉一遍可疑频道名清单,输出封禁状态与内部原因,用于审计核对。

2.4 解封频道:unban-channel

printf 'y\n' | node bin/admin.js unban-channel movie-night

实测回显:

Unban movie-night? Unban succeeded.

解封后再次查询确认:

Channel movie-night is not banned.

同时主日志记录解封事件(实测):

[INFO] BannedChannelsController: Unbanning channel movie-night

封禁→查询→解封→复核,四步闭环完成。被踢的观众无需任何处理即可重新加入频道(频道状态从数据库重新加载)。

2.5 交互式通道 servcmd.sh.js 与内部命令

servcmd.sh.js 是另一条交互式入口:连上 service.sock 后自动实时回放 events.log/sys.log/error.log 三个日志流,并支持 Tab 补全。实测连入(管道模拟键盘输入 /gc 后 exit):

c>
events: [Wed Oct 28 2026 15:49:22] [acp] [console] banned channel movie-night
events: [Wed Oct 28 2026 15:49:40] [acp] [console] unbanned channel movie-night
events: [Wed Oct 28 2026 16:00:45] [acp] [console] banned channel movie-night
events: [Wed Oct 28 2026 16:00:51] [acp] [console] unbanned channel movie-night

历史封禁事件全部实时回显——这个"连入即监控"的特性使它可当作简易日志跟踪器用。

两个实测踩坑必须交代:

  1. 补全清单里的部分命令已失效。脚本内置的 Tab 补全列表有 9 个命令(/delete_old_tables、/gc、/globalban、/reload、/reloadcert、/reload-partitions、/switch、/unglobalban、/unloadchan),但对照 3.86.1 源码 src/main.js 的命令分发器,实际支持的是:/reload(重载配置)、/switch <名> [on|off](功能开关)、/reload-partitions、/save(强制保存全部频道)、/unloadchan <频道>(强制卸载频道并踢出观众)、/reloadcert(重载证书)。/gc、/globalban、/unglobalban、/delete_old_tables 是老版本遗留,发过去不会有任何响应(实测 /gc 等待超时无回包)。
  2. 脚本有上游笔误,收到套接字回包即崩溃。实测向通道发命令后收到服务端响应时脚本抛异常退出,堆栈指向 servcmd.sh.js:74——源码通用回包处理器把收到的变量 msg 误写成了未定义的 data(console.log('server: ', data))。好在多数命令只写日志不回包,所以平时能用;一旦触发回包就会崩。结论:脚本化运维请用 bin/admin.js(JSON 协议,实测稳定),servcmd.sh.js 仅作人工观察窗。

三、频道管理实战

频道生命周期里运维最常打交道的三个动作与它们的日志指纹:

频道加载(有观众加入时触发,实测):

[INFO] ioserver: Accepted socket from 10.89.60.1
[INFO] user: 10.89.60.1 logged in as admin
[INFO] channel: 10.89.60.1 joined movie-night

频道卸载(观众清空后自动回收,实测):

[INFO] ioserver: 10.89.60.1 disconnected (transport close)
[INFO] server: Unloaded channel movie-night

频道状态强制保存(/save 命令或周期任务触发,实测):

[INFO] bgtask: Saving channels with delay 60000
[INFO] bgtask: Saved /r/movie-night

配合数据库取证是频道管理的日常三板斧。常用取证 SQL(实测通过):

# 频道清单与所有者
mariadb -ucytube3 -pq1w2e3r4 cytube3 -e 'select id,name,owner from channels;'
# 账号与全局等级
mariadb -ucytube3 -pq1w2e3r4 cytube3 -e 'select id,name,global_rank from users;'
# 某频道的频道内等级分配
mariadb -ucytube3 -pq1w2e3r4 cytube3 -e 'select * from channel_ranks;'

实测回显(前两条):

id	name	owner
1	movie-night	admin
2	lab-room	tester01

id	name	global_rank
1	admin	255
2	tester01	255
3	co-admin	1
4	co-admin2	1
5	dadmin	1

💡 技术拓展:频道内的权限(版主/管理员)存 channel_ranks 表,播放列表等频道状态存 channel_data 表(3.x 起按模块分行落库)。手工改库后必须让频道重新加载才生效——把频道里的观众清空等它卸载,或用 /unloadchan <频道> 强制卸载,下次加入时从库里重读。

四、备份与恢复实测

4.1 备份对象盘点

CyTube 的全部持久状态只有两类:

  1. 数据库:14 张表(用户、频道、频道状态、媒体库、封禁、别名等,清单见部署篇 4.2 节);
  2. 配置文件:config.yaml 与 conf/ 下的扩展配置(含 cookie-secret,丢了它所有登录态失效)。

特别提醒:官方 Wiki 老文档里"备份 chandump 目录"的建议是 2.x 时代文件存储的产物。3.86.1 实测确认频道状态已全部落 channel_data 表(含 playlist、motd、聊天缓冲等 7 类模块键),chandump/ 目录实测始终为空——数据库就是唯一真相源,备份数据库就是备份一切。

4.2 数据库导出

用应用侧自带的 MariaDB 客户端做全库导出(密码随命令行传入仅限实验环境,生产用选项文件或交互输入):

mariadb-dump -ucytube3 -pq1w2e3r4 cytube3 > backup-cytube3-$(date +%F).sql
wc -l backup-cytube3-*.sql

实测回显:

462 backup-pre.sql

462 行的转储里包含全部 14 张表的 CREATE TABLE 与数据 INSERT(实测 grep -c 'CREATE TABLE' 计数为 14)。再把配置与运行目录一起打包归档:

tar czf cytube-conf-backup-$(date +%F).tar.gz conf/ chandump/ logs/

实测归档产物:

-rw-r--r-- 1 root root 1051 Oct 29 00:01 chandump-backup-20261028.tar.gz

4.3 恢复演练(删库重建全流程)

真实演练一次"库没了怎么办"——删库、重建空库、从备份导回、逐项核对:

# 第一步:删库并重建空库(保持原字符集)
mariadb -uroot -pq1w2e3r4 -e 'DROP DATABASE cytube3; CREATE DATABASE cytube3 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'
mariadb -uroot -pq1w2e3r4 -e "GRANT ALL ON cytube3.* TO 'cytube3'@'%'; FLUSH PRIVILEGES;"

# 第二步:确认空库
mariadb -ucytube3 -pq1w2e3r4 cytube3 -e 'show tables;'
# 实测回显:空(无任何输出)

# 第三步:从备份导回
mariadb -ucytube3 -pq1w2e3r4 cytube3 < backup-pre.sql

实测导回瞬间完成,逐项核对:

mariadb -ucytube3 -pq1w2e3r4 cytube3 -e 'select id,name,global_rank from users; select id,name,owner from channels; select count(*) as lib_rows from channel_libraries; select count(*) as tables_cnt from information_schema.tables where table_schema="cytube3";'

实测回显:

id	name	global_rank
1	admin	255
id	name	owner
1	movie-night	admin
lib_rows
1
tables_cnt
14

管理员账号、频道、媒体库行数、14 张表全部复原。恢复期间应用无需重启——数据库连接池会自动重建连接,恢复完成后 Web 与实时通道实测探活正常(HTTP 200)。

💡 技术拓展:恢复演练建议每个季度做一次,并遵守"演练用备份、生产用双份"原则——本次演练用的 backup-pre.sql 就是演练前一刻新导出的快照。若要纳入定时任务,凌晨低峰执行 mariadb-dump --single-transaction(InnoDB 一致性快照不锁表)加异机传送是标准做法。

五、日志体系与排障

5.1 四个日志文件

3.86.1 在应用运行目录根下写四个日志文件(实测清单):

-rw-r--r-- 1 cytube cytube  527 /opt/cytube/error.log
-rw-r--r-- 1 cytube cytube  142 /opt/cytube/events.log
-rw-r--r-- 1 cytube cytube   90 /opt/cytube/http.log
-rw-r--r-- 1 cytube cytube 1666 /opt/cytube/sys.log
文件内容排障优先级
sys.log主日志:进房/退房、频道加载卸载、限流清理第二
error.log错误与堆栈第一(有异常先看它)
events.log关键事件:注册、封禁/解封、强制卸载审计用
http.logHTTP 请求级日志接口问题用

注意:这些文件写死在运行目录根(不是 logs/ 子目录);编排部署时若挂载了 logs/ 目录会发现它是空的——真实位置与处置方案见《CyTube Docker Compose 部署实战》8.5 节。此外编排/服务化部署下应用输出也进服务日志通道,可当作 sys.log 的镜像使用。

5.2 典型错误检索实战

error.log 的实测内容(原样照抄,三条错误全部定位过):

[Wed Oct 28 2026 15:45:06] [ERROR] google2vtt: Error: ENOENT: no such file or directory, scandir '/opt/cytube/google-drive-subtitles'
[Wed Oct 28 2026 15:45:27] [ERROR] peertubelist: Failed to initialize peertube host list: Error: connect ECONNREFUSED 31.13.94.7:443
[Wed Oct 28 2026 15:45:27] [ERROR] torlist: Unable to load Tor exit list: Error: connect ECONNREFUSED 209.145.54.50:443

判定口诀:

  • google2vtt 的 ENOENT:Google Drive 字幕目录缺失,该功能官方已弃用,可忽略;
  • peertubelist / torlist 的 ECONNREFUSED:启动时联网拉取 PeerTube 实例清单与 Tor 出口清单失败,隔离网络下的预期行为,不影响主功能;能出网的环境重启即自动恢复;
  • 真正要警惕的是 JIT 之外的新增 ERROR:比如 Failed to save /r/<频道>(频道状态保存失败,立即查数据库连接与磁盘),或数据库连接类堆栈。建议巡检脚本对比上次快照的 error.log 增量。

sys.log 里最有价值的两条运维指纹(实测原样照抄):

[Wed Oct 28 2026 15:49:37] [INFO] user: 10.89.60.1 (admin) was kicked: "Channel could not be loaded: Channel is banned: 测试封禁:运维篇演示"
[Wed Oct 28 2026 15:55:06] [INFO] ioserver: Cleaned up 1 stale IP throttle token buckets

前者证明封禁策略在实时生效(用户被踢的完整原因链),后者是限流器的周期自洁——看到它说明限流器工作正常。

六、升级实录

CyTube 3.0 分支滚动发布,升级 = 拉新源码 + 重装依赖 + 重启。先核验当前版本基线(实测):

cd /opt/cytube-lab/stack/cytube-src
git log -1 --format='%h %ad %s' --date=short
grep '"version"' package.json

实测回显:

a656127 2026-10-01 Bump fast-uri from 3.1.0 to 3.1.8 (#1026)
3.86.1

标准升级流程(官方安装指南路径的自然延伸):

cd /opt/cytube-lab/stack/cytube-src

# 1. 查看落后多少提交(评估升级风险)
git fetch origin
git log HEAD..origin/3.0 --oneline | head -20

# 2. 拉取更新
git pull origin 3.0

# 3. 重装依赖(必须以普通用户执行,root 会跳过 postinstall 导致构建不完整)
npm install

# 4. 重启应用进程,确认新版本号
#    日志应出现 Starting CyTube v<新版本号>

三条实测沉淀的经验:

  1. 升级前先备份(第四节流程,462 行转储 10 秒内完成)——3.x 的数据库迁移在应用启动时自动执行且一般单向,回退版本可能撞表结构问题;
  2. npm install 之后检查 lib/ 目录:ls lib | head 确认源码构建产物存在,缺了就是踩了 root/npm 的 postinstall 坑,用普通用户重装即可;
  3. 升级窗口选无观众的时段:重启即频道全部卸载,观众端表现为连接断开重连。重启后用第五节的日志指纹(Starting CyTube v3.86.1 后的核心行)与端口探活做健康确认。

七、故障速查表

现象一手定位处置
观众进频道被踢 "Channel is banned"show-banned-channel <名>确认后 unban-channel
观众登录报 Guest logins are restricted配置 guest-login-delay 限流等间隔或改用注册账号
队列加视频报 already on the playlist频道去重开关换链接或频道设置开启允许重复
error.log 出现 ECONNREFUSEDpeertubelist/torlist 启动自检隔离网络可忽略,出网后自愈
logs/ 目录为空3.86.1 日志写运行目录根改挂载四文件或走服务日志通道
频道设置改了重启后丢失未触发保存(无在线观众不保存)有人在时改,或连套接字发 /save
手工改库不生效频道仍在内存运行清空观众等卸载或 /unloadchan
npm install 后启动报缺 lib 模块root 执行跳过 postinstall普通用户重装依赖

八、参考链接