TS3AudioBot Docker 迁移技术文档

由 Markdown 技术文档生成的 wiki 页面。公开版已对敏感服务器信息做占位符脱敏。

返回技术导航 返回首页文章
Source: 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. 原始运行信息

原进程信息:

bash
<TS3AudioBot 程序目录>/TS3AudioBot --non-interactive --stats-disabled --config <TS3AudioBot 数据目录>/ts3audiobot.toml

原工作目录:

bash
<TS3AudioBot 数据目录>

原程序目录:

bash
<TS3AudioBot 程序目录>

原数据目录:

bash
<TS3AudioBot 数据目录>

原 TS3AudioBot 版本:

text
0.12.0/master/768c1867

这是一个较老版本,运行时依赖较旧的系统库,例如 OpenSSL 1.1。

---

3. 当前 Docker 项目结构

Docker 项目目录:

bash
<TS3AudioBot compose 目录>

建议结构:

text
<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/

容器内对应路径:

text
<TS3AudioBot 程序目录>          TS3AudioBot 程序目录
<TS3AudioBot 数据目录>      TS3AudioBot 数据目录,来自宿主机 ./data 挂载
/usr/local/bin/yt-dlp     yt-dlp 可执行文件
/usr/bin/ffmpeg           ffmpeg 可执行文件

---

4. Docker 镜像关键点

最终应使用 Debian Bullseye 系列基础镜像,而不是 Bookworm:

dockerfile
FROM debian:bullseye-slim

原因:

  • TS3AudioBot 当前版本基于较旧的 .NET Core / .NET Framework 运行时。
  • Bookworm 默认提供 libssl3,但该 TS3AudioBot 需要能使用 OpenSSL 1.1。
  • 使用 Bookworm 时会出现:
text
No usable version of libssl was found
Aborted (core dumped)

镜像内需要安装的关键依赖:

text
ca-certificates
tzdata
tini
python3
ffmpeg
libicu67
libssl1.1
zlib1g
libsqlite3-0
libopus0
libsodium23
libstdc++6

需要设置:

dockerfile
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1

旧版 TS3AudioBot 在容器环境中可能找不到部分库的无版本 .so 名称,因此需要补软链接:

bash
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

如果没有软链接,日志里可能出现:

text
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、数据库和权限文件提交到公开仓库。

参考结构:

yaml
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 配置关键点

配置文件:

bash
<TS3AudioBot compose 目录>/data/ts3audiobot.toml

容器内路径:

bash
<TS3AudioBot 数据目录>/ts3audiobot.toml

6.1 ffmpeg 路径

容器内 ffmpeg 在:

bash
/usr/bin/ffmpeg

因此配置应为:

toml
[tools.ffmpeg]
path = "/usr/bin/ffmpeg"

如果仍配置成旧路径:

toml
path = "/usr/local/bin/ffmpeg"

会出现:

text
Ffmpeg could not be found (No such file or directory)

6.2 youtube-dl / yt-dlp 路径

原配置中使用过:

toml
[tools]
youtube-dl = { path = "/usr/local/bin/yt-dlp-bili" }

这说明原来的 Bilibili 播放并不是单纯调用官方 youtube-dl,而是经过自定义包装入口。

Docker 中需要确保以下至少一个路径可用,具体以插件和配置使用的路径为准:

bash
/usr/local/bin/yt-dlp
/usr/local/bin/yt-dlp-bili

检查命令:

bash
docker exec ts3audiobot sh -c 'command -v yt-dlp; command -v yt-dlp-bili 2>/dev/null || true'

6.3 命令匹配模式

原部署里命令匹配模式改过:

toml
matcher = "exact"

如果出现自定义命令匹配异常,应检查该配置是否仍与原环境一致。

---

7. !bili 的真实实现

!bili 来自插件:

bash
<TS3AudioBot 数据目录>/plugins/<Bilibili 命令插件>

宿主机 Docker 数据目录中对应:

bash
<TS3AudioBot compose 目录>/data/plugins/<Bilibili 命令插件>

工作流程:

text
用户输入 !bili BV号
-> <Bilibili 命令插件> 插件接管命令
-> 调用 yt-dlp / yt-dlp-bili
-> 使用 <Bilibili cookies 文件> 解析 Bilibili 音频
-> 下载并保存为本地 mp3
-> 调用 TS3AudioBot 播放本地文件

所以 !bili 本质上是“下载后播放”,不是 TS3AudioBot 原生在线播放。

下载目录通常是:

bash
<TS3AudioBot 数据目录>/bots/default/music/bili/

这个目录必须让容器内的 ts3ab 用户可写。

检查命令:

bash
docker exec ts3audiobot sh -c 'ls -ld <TS3AudioBot 数据目录>/bots/default/music/bili'

---

8. Bilibili HTTP 代理

当前还有一个 Python 代理:

bash
<TS3AudioBot 程序目录>/<Bilibili 音频代理脚本>

监听地址:

text
127.0.0.1:<Bilibili 代理端口>

支持路径:

text
/bv/BV号
/bv/BV号.mp3
/stream?src=完整B站链接

它会调用:

bash
/usr/local/bin/yt-dlp

并读取 cookies:

bash
<TS3AudioBot 数据目录>/<Bilibili cookies 文件>

备用播放方式:

text
!play http://127.0.0.1:<Bilibili 代理端口>/bv/BV1gK4y1a7yZ.mp3

如果 !bili 插件暂时没有加载,但代理正常,这条路径可作为临时播放方案。

---

9. 插件自动加载

容器重启后,<Bilibili 命令插件> 文件存在并不代表插件已经启用。

常见现象:

text
!bili BV1gK4y1a7yZ

返回:

text
Error: The command contains the following subfunctions: unsubscribe, version, volume, ...

并且列表里没有 bili

这说明 <Bilibili 命令插件> 没有加载。

9.1 手动加载方式

在 TeamSpeak 聊天中执行:

text
!plugin load <Bilibili 命令插件>

然后检查:

text
!plugin list

正常结果:

text
All available plugins:
#0|+ON|BiliUrlPlugin (BotPlugin)

之后再执行:

text
!bili BV1gK4y1a7yZ

正常回复:

text
Downloading and will play when ready: BV1gK4y1a7yZ

9.2 API 加载注意事项

直接调用全局 API 会缺少 bot 上下文:

bash
curl -i 'http://127.0.0.1:<TS3AudioBot Web API 端口>/api/plugin/load/<Bilibili 命令插件>'

错误:

json
{"ErrorName":"CommandError","ErrorMessage":"Plugin error: MissingContext"}

因此插件加载必须在 bot 上下文中执行。当前 bot id 从日志看是 0

text
INFO|0| User ...

可通过 Web API 检查插件状态:

bash
curl -s 'http://127.0.0.1:<TS3AudioBot Web API 端口>/api/plugin/list'

插件正常加载后应能看到类似:

json
[{"Id":0,"Name":"BiliUrlPlugin (BotPlugin)","Status":5,"Type":1}]

9.3 entrypoint 自动加载思路

entrypoint.sh 的核心逻辑应包括:

  1. 准备目录和权限。
  2. 启动 <Bilibili 音频代理脚本>
  3. 启动 TS3AudioBot。
  4. 等 Web API 可用后,自动执行一次插件加载。
  5. 保持前台进程等待 TS3AudioBot 退出。

参考结构:

sh
#!/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. 权限文件

权限文件:

bash
<TS3AudioBot compose 目录>/data/<TS3AudioBot 权限文件>

容器内:

bash
<TS3AudioBot 数据目录>/<TS3AudioBot 权限文件>

普通用户要能使用 !bili,需要放行:

toml
"cmd.bili",
"cmd.bili.*"

如果日志里出现:

text
Right "cmd.bili" is not registered.

通常表示插件当时还没加载,导致权限系统尚未注册这个命令。先确认:

text
!plugin list

看到:

text
#0|+ON|BiliUrlPlugin (BotPlugin)

再测试 !bili

---

11. 常用操作命令

进入 Docker 项目目录:

bash
cd <TS3AudioBot compose 目录>

重新 build 并重建容器:

bash
docker compose up -d --build --force-recreate

查看容器状态:

bash
docker ps

查看 TS3AudioBot 日志:

bash
docker logs --tail=120 ts3audiobot

持续查看日志:

bash
docker logs -f ts3audiobot

查看插件自动加载日志:

bash
tail -100 data/plugin-load.log

检查关键文件:

bash
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 状态:

bash
curl -s 'http://127.0.0.1:<TS3AudioBot Web API 端口>/api/plugin/list'

---

12. 验证清单

容器启动后按顺序检查:

bash
docker ps

应看到:

text
ts3audiobot ... Up ...

查看日志:

bash
docker logs --tail=120 ts3audiobot

应看到类似:

text
TS3AudioBot started
Version: 0.12.0/master/768c1867
Opus: libopus ...
Starting Webserver on port <TS3AudioBot Web API 端口>
Client connected.

TeamSpeak 内检查:

text
!plugin list

应看到:

text
#0|+ON|BiliUrlPlugin (BotPlugin)

测试 Bilibili:

text
!bili BV1gK4y1a7yZ

应回复:

text
Downloading and will play when ready: BV1gK4y1a7yZ

如果只想测试代理:

text
!play http://127.0.0.1:<Bilibili 代理端口>/bv/BV1gK4y1a7yZ.mp3

---

13. 常见问题与处理

13.1 容器一直 Restarting,日志显示 libssl

现象:

text
No usable version of libssl was found
Aborted (core dumped)

原因:

text
基础镜像太新,例如 debian:bookworm-slim 只有 libssl3。

处理:

text
改用 debian:bullseye-slim,并安装 libssl1.1。

13.2 sed: can't read /etc/apt/sources.list

现象:

text
sed: can't read /etc/apt/sources.list: No such file or directory

原因:

text
不同 Debian 版本的 apt 源文件位置可能不同。

处理:

text
不要假设一定有 /etc/apt/sources.list。
可以直接使用 bullseye-slim 默认源,或显式写入自己的 sources.list。

13.3 libopus 找不到

现象:

text
Failed to load library "libopus".
Couldn't find libopus.

检查:

bash
docker run --rm --entrypoint sh ts3audiobot-docker-ts3audiobot -c \
'find /usr/lib -name "libopus.so*" -o -name "libsodium.so*"'

如果只有:

text
libopus.so.0
libsodium.so.23

需要补:

bash
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

13.4 ffmpeg 找不到

现象:

text
Ffmpeg could not be found (No such file or directory)

检查:

bash
docker exec ts3audiobot sh -c 'command -v ffmpeg; ls -l /usr/bin/ffmpeg /usr/local/bin/ffmpeg 2>/dev/null'

如果输出:

text
/usr/bin/ffmpeg

就把配置改为:

toml
[tools.ffmpeg]
path = "/usr/bin/ffmpeg"

13.5 !bili 返回一大串基础命令

现象:

text
Error: The command contains the following subfunctions: unsubscribe, version, volume, ...

原因:

text
<Bilibili 命令插件> 插件没有加载,bot 不认识 bili 命令。

处理:

text
!plugin load <Bilibili 命令插件>
!plugin list
!bili BV1gK4y1a7yZ

并检查自动加载日志:

bash
tail -100 <TS3AudioBot compose 目录>/data/plugin-load.log

13.6 alias 方式不可取

曾尝试过:

text
!alias add bili ...

结果并不能恢复原来的 !bili

原因:

text
原来的 !bili 是插件命令,不是 alias。
TS3AudioBot 的 alias 解析方式也不会按预期把复杂命令表达式重新执行成 plugin 命令。

正确方向:

text
加载 <Bilibili 命令插件> 插件。

13.7 Bilibili 解析失败

优先检查:

bash
docker exec ts3audiobot sh -c '
  ls -l <TS3AudioBot 数据目录>/<Bilibili cookies 文件>
  command -v yt-dlp
  command -v yt-dlp-bili 2>/dev/null || true
'

同时查看:

bash
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. 备份与迁移

迁移或重装前,至少备份:

bash
<TS3AudioBot compose 目录>/data

其中最关键的是:

text
ts3audiobot.toml
<TS3AudioBot 权限文件>
<TS3AudioBot 数据库文件>
<Bilibili cookies 文件>
plugins/<Bilibili 命令插件>
bots/default/

建议备份命令:

bash
cd <TS3AudioBot compose 目录>
tar -czf ts3audiobot-data-backup-$(date +%F).tar.gz data

如果要迁移到新服务器:

  1. 安装 Docker 和 Docker Compose。
  2. 复制整个 <TS3AudioBot compose 目录>
  3. 确认 data 目录权限。
  4. 重新 build。
  5. 启动容器。
  6. 在 TeamSpeak 内验证 !plugin list!bili

---

15. 安全注意事项

  • <Bilibili cookies 文件> 等同于 Bilibili 登录凭证,不要公开。
  • <TS3AudioBot 数据库文件> 可能包含 bot 状态、历史数据和配置,不要公开。
  • <TS3AudioBot 权限文件> 影响谁能控制 bot,修改前应备份。
  • Web API 端口 <TS3AudioBot Web API 端口> 不建议暴露到公网。
  • 如果必须远程访问 Web UI,建议使用防火墙、反向代理认证或 SSH 隧道。
  • 容器应尽量使用非 root 用户运行 TS3AudioBot。

---

16. 最小恢复流程

如果未来容器坏了,但数据还在,可以按这个最短流程恢复:

bash
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.log

TeamSpeak 内:

text
!plugin list
!bili BV1gK4y1a7yZ

如果 !plugin list 没看到 BiliUrlPlugin

text
!plugin load <Bilibili 命令插件>
!plugin list
!bili BV1gK4y1a7yZ

---

17. 最终结论

这次迁移的核心不是“把一个 TS3AudioBot 二进制放进 Docker”这么简单,而是要把以下整套环境一起迁移:

text
TS3AudioBot 本体
旧版运行库依赖
ffmpeg
yt-dlp / yt-dlp-bili
Bilibili cookies
<Bilibili 命令插件> 插件
插件自动加载逻辑
<TS3AudioBot 权限文件> 权限
<TS3AudioBot 数据库文件> 数据库
bots/default/music/bili 下载目录
<Bilibili 音频代理脚本> 备用代理

只要这些组件都在,且 <Bilibili 命令插件> 成功加载,!bili BV号 就能恢复工作。