ts3audiobot/TS3AudioBot Docker 迁移技术文档.md文档日期:2026-07-08 适用对象:当前服务器上的 TS3AudioBot + 自定义 !bili Bilibili 播放功能 当前已验证状态:Docker 容器可启动,TS3AudioBot 可连接 TeamSpeak,!bili 插件可加载并可用。
---
1. 背景与目标
原服务器上已经运行了一套 TS3AudioBot,并且做过自定义改造:
- TS3AudioBot 本体负责连接 TeamSpeak 并播放音乐。
ffmpeg负责转码和播放链路。yt-dlp/yt-dlp-bili负责解析 Bilibili 音频。<Bilibili cookies 文件>提供 Bilibili 登录态,解决部分视频无法解析的问题。<Bilibili 命令插件>插件提供真正的!bili指令。<Bilibili 音频代理脚本>提供一个本机 HTTP 音频代理,可作为 Bilibili 播放的备用路径。
迁移目标是:
- 把 TS3AudioBot 搬进 Docker。
- 保留原来的配置、数据库、权限和插件。
- 保留
!bili BV号的使用方式。 - 保留 Bilibili cookies、下载目录和历史数据。
- 重启容器后自动恢复可用状态。
需要特别注意:!bili 不是 TS3AudioBot 原生命令,而是自定义插件 <Bilibili 命令插件> 注册出来的命令。只运行 TS3AudioBot 本体时,!bili 一定会消失。
---
2. 原始运行信息
原进程信息:
<TS3AudioBot 程序目录>/TS3AudioBot --non-interactive --stats-disabled --config <TS3AudioBot 数据目录>/ts3audiobot.toml原工作目录:
<TS3AudioBot 数据目录>原程序目录:
<TS3AudioBot 程序目录>原数据目录:
<TS3AudioBot 数据目录>原 TS3AudioBot 版本:
0.12.0/master/768c1867这是一个较老版本,运行时依赖较旧的系统库,例如 OpenSSL 1.1。
---
3. 当前 Docker 项目结构
Docker 项目目录:
<TS3AudioBot compose 目录>建议结构:
<TS3AudioBot compose 目录>
├── Dockerfile
├── docker-compose.yml
├── entrypoint.sh
├── yt-dlp
├── app/
│ ├── TS3AudioBot
│ ├── WebInterface/
│ └── <Bilibili 音频代理脚本>
└── data/
├── ts3audiobot.toml
├── <TS3AudioBot 权限文件>
├── <TS3AudioBot 数据库文件>
├── <Bilibili cookies 文件>
├── bili-command.log
├── yt-dlp-bili.log
├── plugins/
│ └── <Bilibili 命令插件>
├── bots/
│ └── default/
│ └── music/
│ └── bili/
└── logs/容器内对应路径:
<TS3AudioBot 程序目录> TS3AudioBot 程序目录
<TS3AudioBot 数据目录> TS3AudioBot 数据目录,来自宿主机 ./data 挂载
/usr/local/bin/yt-dlp yt-dlp 可执行文件
/usr/bin/ffmpeg ffmpeg 可执行文件---
4. Docker 镜像关键点
最终应使用 Debian Bullseye 系列基础镜像,而不是 Bookworm:
FROM debian:bullseye-slim原因:
- TS3AudioBot 当前版本基于较旧的 .NET Core / .NET Framework 运行时。
- Bookworm 默认提供
libssl3,但该 TS3AudioBot 需要能使用 OpenSSL 1.1。 - 使用 Bookworm 时会出现:
No usable version of libssl was found
Aborted (core dumped)镜像内需要安装的关键依赖:
ca-certificates
tzdata
tini
python3
ffmpeg
libicu67
libssl1.1
zlib1g
libsqlite3-0
libopus0
libsodium23
libstdc++6需要设置:
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1旧版 TS3AudioBot 在容器环境中可能找不到部分库的无版本 .so 名称,因此需要补软链接:
ln -sf /usr/lib/x86_64-linux-gnu/libopus.so.0 /usr/lib/x86_64-linux-gnu/libopus.so
ln -sf /usr/lib/x86_64-linux-gnu/libsodium.so.23 /usr/lib/x86_64-linux-gnu/libsodium.so如果没有软链接,日志里可能出现:
Failed to load library "libopus".
Couldn't find libopus. Make sure it is installed or placed in the correct folder.---
5. docker-compose 要点
核心原则:
- 挂载
./data到<TS3AudioBot 数据目录>。 - 使用
restart: unless-stopped或等价策略。 - Web API 端口如需暴露,建议只绑定到本机
127.0.0.1。 - 不要把 Bilibili cookies、数据库和权限文件提交到公开仓库。
参考结构:
services:
ts3audiobot:
build: .
container_name: ts3audiobot
restart: unless-stopped
ports:
- "127.0.0.1:<TS3AudioBot Web API 端口>:<TS3AudioBot Web API 端口>"
volumes:
- ./data:<TS3AudioBot 数据目录>
command:
- --non-interactive
- --stats-disabled
- --config
- <TS3AudioBot 数据目录>/ts3audiobot.toml如果 TS3AudioBot Web API 不需要被宿主机访问,可以不映射端口;但当前排障和自动加载插件都会用到 <TS3AudioBot Web API 端口>,所以建议保留本机绑定。
---
6. TS3AudioBot 配置关键点
配置文件:
<TS3AudioBot compose 目录>/data/ts3audiobot.toml容器内路径:
<TS3AudioBot 数据目录>/ts3audiobot.toml6.1 ffmpeg 路径
容器内 ffmpeg 在:
/usr/bin/ffmpeg因此配置应为:
[tools.ffmpeg]
path = "/usr/bin/ffmpeg"如果仍配置成旧路径:
path = "/usr/local/bin/ffmpeg"会出现:
Ffmpeg could not be found (No such file or directory)6.2 youtube-dl / yt-dlp 路径
原配置中使用过:
[tools]
youtube-dl = { path = "/usr/local/bin/yt-dlp-bili" }这说明原来的 Bilibili 播放并不是单纯调用官方 youtube-dl,而是经过自定义包装入口。
Docker 中需要确保以下至少一个路径可用,具体以插件和配置使用的路径为准:
/usr/local/bin/yt-dlp
/usr/local/bin/yt-dlp-bili检查命令:
docker exec ts3audiobot sh -c 'command -v yt-dlp; command -v yt-dlp-bili 2>/dev/null || true'6.3 命令匹配模式
原部署里命令匹配模式改过:
matcher = "exact"如果出现自定义命令匹配异常,应检查该配置是否仍与原环境一致。
---
7. !bili 的真实实现
!bili 来自插件:
<TS3AudioBot 数据目录>/plugins/<Bilibili 命令插件>宿主机 Docker 数据目录中对应:
<TS3AudioBot compose 目录>/data/plugins/<Bilibili 命令插件>工作流程:
用户输入 !bili BV号
-> <Bilibili 命令插件> 插件接管命令
-> 调用 yt-dlp / yt-dlp-bili
-> 使用 <Bilibili cookies 文件> 解析 Bilibili 音频
-> 下载并保存为本地 mp3
-> 调用 TS3AudioBot 播放本地文件所以 !bili 本质上是“下载后播放”,不是 TS3AudioBot 原生在线播放。
下载目录通常是:
<TS3AudioBot 数据目录>/bots/default/music/bili/这个目录必须让容器内的 ts3ab 用户可写。
检查命令:
docker exec ts3audiobot sh -c 'ls -ld <TS3AudioBot 数据目录>/bots/default/music/bili'---
8. Bilibili HTTP 代理
当前还有一个 Python 代理:
<TS3AudioBot 程序目录>/<Bilibili 音频代理脚本>监听地址:
127.0.0.1:<Bilibili 代理端口>支持路径:
/bv/BV号
/bv/BV号.mp3
/stream?src=完整B站链接它会调用:
/usr/local/bin/yt-dlp并读取 cookies:
<TS3AudioBot 数据目录>/<Bilibili cookies 文件>备用播放方式:
!play http://127.0.0.1:<Bilibili 代理端口>/bv/BV1gK4y1a7yZ.mp3如果 !bili 插件暂时没有加载,但代理正常,这条路径可作为临时播放方案。
---
9. 插件自动加载
容器重启后,<Bilibili 命令插件> 文件存在并不代表插件已经启用。
常见现象:
!bili BV1gK4y1a7yZ返回:
Error: The command contains the following subfunctions: unsubscribe, version, volume, ...并且列表里没有 bili。
这说明 <Bilibili 命令插件> 没有加载。
9.1 手动加载方式
在 TeamSpeak 聊天中执行:
!plugin load <Bilibili 命令插件>然后检查:
!plugin list正常结果:
All available plugins:
#0|+ON|BiliUrlPlugin (BotPlugin)之后再执行:
!bili BV1gK4y1a7yZ正常回复:
Downloading and will play when ready: BV1gK4y1a7yZ9.2 API 加载注意事项
直接调用全局 API 会缺少 bot 上下文:
curl -i 'http://127.0.0.1:<TS3AudioBot Web API 端口>/api/plugin/load/<Bilibili 命令插件>'错误:
{"ErrorName":"CommandError","ErrorMessage":"Plugin error: MissingContext"}因此插件加载必须在 bot 上下文中执行。当前 bot id 从日志看是 0:
INFO|0| User ...可通过 Web API 检查插件状态:
curl -s 'http://127.0.0.1:<TS3AudioBot Web API 端口>/api/plugin/list'插件正常加载后应能看到类似:
[{"Id":0,"Name":"BiliUrlPlugin (BotPlugin)","Status":5,"Type":1}]9.3 entrypoint 自动加载思路
entrypoint.sh 的核心逻辑应包括:
- 准备目录和权限。
- 启动
<Bilibili 音频代理脚本>。 - 启动 TS3AudioBot。
- 等 Web API 可用后,自动执行一次插件加载。
- 保持前台进程等待 TS3AudioBot 退出。
参考结构:
#!/bin/sh
set -eu
DATA_DIR="<TS3AudioBot 数据目录>"
APP_DIR="<TS3AudioBot 程序目录>"
LOG_FILE="$DATA_DIR/plugin-load.log"
mkdir -p "$DATA_DIR/bots/default/music/bili"
chown -R ts3ab:ts3ab "$DATA_DIR/bots/default/music" "$DATA_DIR/plugins" 2>/dev/null || true
if [ -f "$APP_DIR/<Bilibili 音频代理脚本>" ]; then
python3 "$APP_DIR/<Bilibili 音频代理脚本>" >> "$DATA_DIR/bili-command.log" 2>&1 &
fi
"$APP_DIR/TS3AudioBot" "$@" &
BOT_PID="$!"
(
i=1
while [ "$i" -le 60 ]; do
if python3 - <<'PY'
import urllib.request
url = "http://127.0.0.1:<TS3AudioBot Web API 端口>/api/bot/use/0/(/plugin/load/<Bilibili 命令插件>)"
try:
with urllib.request.urlopen(url, timeout=3) as resp:
print(resp.status, resp.read().decode("utf-8", "replace"))
raise SystemExit(0)
except Exception as exc:
print(repr(exc))
raise SystemExit(1)
PY
then
echo "$(date '+%F %T') plugin load requested" >> "$LOG_FILE"
exit 0
fi
echo "$(date '+%F %T') waiting for plugin load api, attempt $i" >> "$LOG_FILE"
i=$((i + 1))
sleep 2
done
echo "$(date '+%F %T') plugin load failed after retries" >> "$LOG_FILE"
) &
wait "$BOT_PID"如果你的实际 entrypoint.sh 已经验证可用,以服务器当前版本为准。上面这段用于说明自动加载的关键思路。
---
10. 权限文件
权限文件:
<TS3AudioBot compose 目录>/data/<TS3AudioBot 权限文件>容器内:
<TS3AudioBot 数据目录>/<TS3AudioBot 权限文件>普通用户要能使用 !bili,需要放行:
"cmd.bili",
"cmd.bili.*"如果日志里出现:
Right "cmd.bili" is not registered.通常表示插件当时还没加载,导致权限系统尚未注册这个命令。先确认:
!plugin list看到:
#0|+ON|BiliUrlPlugin (BotPlugin)再测试 !bili。
---
11. 常用操作命令
进入 Docker 项目目录:
cd <TS3AudioBot compose 目录>重新 build 并重建容器:
docker compose up -d --build --force-recreate查看容器状态:
docker ps查看 TS3AudioBot 日志:
docker logs --tail=120 ts3audiobot持续查看日志:
docker logs -f ts3audiobot查看插件自动加载日志:
tail -100 data/plugin-load.log检查关键文件:
docker exec ts3audiobot sh -c '
command -v ffmpeg
command -v yt-dlp
ls -l <TS3AudioBot 数据目录>/<Bilibili cookies 文件>
ls -l <TS3AudioBot 数据目录>/plugins/<Bilibili 命令插件>
ls -ld <TS3AudioBot 数据目录>/bots/default/music/bili
'检查插件 API 状态:
curl -s 'http://127.0.0.1:<TS3AudioBot Web API 端口>/api/plugin/list'---
12. 验证清单
容器启动后按顺序检查:
docker ps应看到:
ts3audiobot ... Up ...查看日志:
docker logs --tail=120 ts3audiobot应看到类似:
TS3AudioBot started
Version: 0.12.0/master/768c1867
Opus: libopus ...
Starting Webserver on port <TS3AudioBot Web API 端口>
Client connected.TeamSpeak 内检查:
!plugin list应看到:
#0|+ON|BiliUrlPlugin (BotPlugin)测试 Bilibili:
!bili BV1gK4y1a7yZ应回复:
Downloading and will play when ready: BV1gK4y1a7yZ如果只想测试代理:
!play http://127.0.0.1:<Bilibili 代理端口>/bv/BV1gK4y1a7yZ.mp3---
13. 常见问题与处理
13.1 容器一直 Restarting,日志显示 libssl
现象:
No usable version of libssl was found
Aborted (core dumped)原因:
基础镜像太新,例如 debian:bookworm-slim 只有 libssl3。处理:
改用 debian:bullseye-slim,并安装 libssl1.1。13.2 sed: can't read /etc/apt/sources.list
现象:
sed: can't read /etc/apt/sources.list: No such file or directory原因:
不同 Debian 版本的 apt 源文件位置可能不同。处理:
不要假设一定有 /etc/apt/sources.list。
可以直接使用 bullseye-slim 默认源,或显式写入自己的 sources.list。13.3 libopus 找不到
现象:
Failed to load library "libopus".
Couldn't find libopus.检查:
docker run --rm --entrypoint sh ts3audiobot-docker-ts3audiobot -c \
'find /usr/lib -name "libopus.so*" -o -name "libsodium.so*"'如果只有:
libopus.so.0
libsodium.so.23需要补:
ln -sf /usr/lib/x86_64-linux-gnu/libopus.so.0 /usr/lib/x86_64-linux-gnu/libopus.so
ln -sf /usr/lib/x86_64-linux-gnu/libsodium.so.23 /usr/lib/x86_64-linux-gnu/libsodium.so13.4 ffmpeg 找不到
现象:
Ffmpeg could not be found (No such file or directory)检查:
docker exec ts3audiobot sh -c 'command -v ffmpeg; ls -l /usr/bin/ffmpeg /usr/local/bin/ffmpeg 2>/dev/null'如果输出:
/usr/bin/ffmpeg就把配置改为:
[tools.ffmpeg]
path = "/usr/bin/ffmpeg"13.5 !bili 返回一大串基础命令
现象:
Error: The command contains the following subfunctions: unsubscribe, version, volume, ...原因:
<Bilibili 命令插件> 插件没有加载,bot 不认识 bili 命令。处理:
!plugin load <Bilibili 命令插件>
!plugin list
!bili BV1gK4y1a7yZ并检查自动加载日志:
tail -100 <TS3AudioBot compose 目录>/data/plugin-load.log13.6 alias 方式不可取
曾尝试过:
!alias add bili ...结果并不能恢复原来的 !bili。
原因:
原来的 !bili 是插件命令,不是 alias。
TS3AudioBot 的 alias 解析方式也不会按预期把复杂命令表达式重新执行成 plugin 命令。正确方向:
加载 <Bilibili 命令插件> 插件。13.7 Bilibili 解析失败
优先检查:
docker exec ts3audiobot sh -c '
ls -l <TS3AudioBot 数据目录>/<Bilibili cookies 文件>
command -v yt-dlp
command -v yt-dlp-bili 2>/dev/null || true
'同时查看:
tail -100 <TS3AudioBot compose 目录>/data/bili-command.log
tail -100 <TS3AudioBot compose 目录>/data/yt-dlp-bili.log常见原因:
- cookies 文件不存在。
- cookies 过期。
yt-dlp路径不对。yt-dlp-bili包装脚本缺失。- Bilibili 视频需要登录或权限。
- 下载目录不可写。
---
14. 备份与迁移
迁移或重装前,至少备份:
<TS3AudioBot compose 目录>/data其中最关键的是:
ts3audiobot.toml
<TS3AudioBot 权限文件>
<TS3AudioBot 数据库文件>
<Bilibili cookies 文件>
plugins/<Bilibili 命令插件>
bots/default/建议备份命令:
cd <TS3AudioBot compose 目录>
tar -czf ts3audiobot-data-backup-$(date +%F).tar.gz data如果要迁移到新服务器:
- 安装 Docker 和 Docker Compose。
- 复制整个
<TS3AudioBot compose 目录>。 - 确认
data目录权限。 - 重新 build。
- 启动容器。
- 在 TeamSpeak 内验证
!plugin list和!bili。
---
15. 安全注意事项
<Bilibili cookies 文件>等同于 Bilibili 登录凭证,不要公开。<TS3AudioBot 数据库文件>可能包含 bot 状态、历史数据和配置,不要公开。<TS3AudioBot 权限文件>影响谁能控制 bot,修改前应备份。- Web API 端口
<TS3AudioBot Web API 端口>不建议暴露到公网。 - 如果必须远程访问 Web UI,建议使用防火墙、反向代理认证或 SSH 隧道。
- 容器应尽量使用非 root 用户运行 TS3AudioBot。
---
16. 最小恢复流程
如果未来容器坏了,但数据还在,可以按这个最短流程恢复:
cd <TS3AudioBot compose 目录>
docker compose down
docker compose up -d --build --force-recreate
sleep 15
docker logs --tail=120 ts3audiobot
tail -100 data/plugin-load.logTeamSpeak 内:
!plugin list
!bili BV1gK4y1a7yZ如果 !plugin list 没看到 BiliUrlPlugin:
!plugin load <Bilibili 命令插件>
!plugin list
!bili BV1gK4y1a7yZ---
17. 最终结论
这次迁移的核心不是“把一个 TS3AudioBot 二进制放进 Docker”这么简单,而是要把以下整套环境一起迁移:
TS3AudioBot 本体
旧版运行库依赖
ffmpeg
yt-dlp / yt-dlp-bili
Bilibili cookies
<Bilibili 命令插件> 插件
插件自动加载逻辑
<TS3AudioBot 权限文件> 权限
<TS3AudioBot 数据库文件> 数据库
bots/default/music/bili 下载目录
<Bilibili 音频代理脚本> 备用代理只要这些组件都在,且 <Bilibili 命令插件> 成功加载,!bili BV号 就能恢复工作。