child-psycho-companion/DEPLOYMENT_GUIDE_LOCAL.md

12 KiB
Raw Blame History

xiaozhi-esp32-server 全模块本地部署指南

目标平台: MacBook Pro M1 Pro (ARM64, 32GB)
系统: macOS Darwin 24.6.0 (arm64)
适用范围: 从当前"仅 server 模块"升级为"server + manager-api + manager-web + MySQL + Redis"全模块
生成时间: 2026-04-06


0. 背景与目标

当前问题: xiaozhi-server 的 LLM 配置被 xinnan-tech 云端 manager-api 覆盖,实际使用了默认的 glm-4-flash 而非 MiniMax导致 401 错误。

解决思路: 升级到全模块部署,智控台配置保存在本地 MySQL 数据库MiniMax API Key 由智控台管理,不再被云端覆盖。


1. 环境概览

当前状态

/Users/bigemon/WorkSpace/xiaozhi-server/
├── docker-compose.yml        ← 单模块server only
├── data/
│   ├── .config.yaml          ← MiniMax 配置(被云端覆盖)
│   └── .mcp_server_settings.json
└── models/
    ├── SenseVoiceSmall/model.pt/  ← 目录,模型在 nested 路径
    ├── snakers4_silero-vad/
    └── mcp-endpoint-server/

部署后架构

┌─────────────────────────────────────────────────────────┐
│ MacBook Pro M1 Pro (32GB)                               │
│                                                         │
│  xiaozhi-esp32-server    8000,8003/tcp  (server)       │
│  xiaozhi-esp32-server-web   8002/tcp    (智控台)        │
│  xiaozhi-esp32-server-db  3306/tcp     (MySQL)         │
│  xiaozhi-esp32-server-redis 6379/tcp   (Redis)         │
│                                                         │
│  docker.for.mac.host.internal ← 容器访问宿主机            │
└─────────────────────────────────────────────────────────┘

ARM64 兼容性确认

镜像 状态 备注
server_latest ARM64 ghcr.nju.edu.cn/xinnan-tech 提供
web_latest ARM64 Spring Boot + Vue无平台依赖
mysql:latest ⚠️ 基本支持 建议改用 mysql:8.0
redis:8.0 ARM64 官方多架构镜像
FunASR SenseVoiceSmall 支持 PyTorch CPU 模式

2. 前置检查

# 1. 端口检查8002 必须空闲)
lsof -i :8002 2>/dev/null | grep LISTEN || echo "8002 空闲 ✅"

# 2. 确认 Docker 可用
docker --version && docker compose version

# 3. 确认现有容器状态
docker ps --format "{{.Names}}\t{{.Status}}" | grep xiaozhi

# 4. 确认模型文件存在
ls /Users/bigemon/WorkSpace/xiaozhi-server/models/SenseVoiceSmall/model.pt/
# 应看到 SenseVoiceSmall.pt 或 nested 目录

# 5. 备份现有配置
cp /Users/bigemon/WorkSpace/xiaozhi-server/data/.config.yaml \
   /Users/bigemon/WorkSpace/xiaozhi-server/data/.config.yaml.bak.$(date +%Y%m%d%H%M%S)

3. 详细部署步骤

Step 1建立目录结构

cd /Users/bigemon/WorkSpace/xiaozhi-server

# MySQL 数据目录
mkdir -p mysql/data

# 最终目录结构应为:
# xiaozhi-server/
# ├── docker-compose_all.yml   ← 新增
# ├── docker-compose.yml       ← 旧文件(可保留备份)
# ├── data/
# │   └── .config.yaml
# ├── models/
# └── mysql/
#     └── data/

Step 2下载 docker-compose_all.yml

cd /Users/bigemon/WorkSpace/xiaozhi-server

# 下载全模块编排文件
wget -q https://raw.githubusercontent.com/xinnan-tech/xiaozhi-esp32-server/refs/heads/main/main/xiaozhi-server/docker-compose_all.yml \
  -O docker-compose_all.yml

# 验证下载
head -20 docker-compose_all.yml

Step 3修复 MySQL 镜像版本(避免 latest 不稳定问题)

# 将 mysql:latest 改为 mysql:8.0
sed -i '' 's|image: mysql:latest|image: mysql:8.0|' docker-compose_all.yml

# 确认修改
grep "image:" docker-compose_all.yml
# 预期mysql:8.0 ✅

Step 4修复 FunASR 模型文件路径

问题: models/SenseVoiceSmall/model.pt目录,但 docker-compose volume 挂载期望它是文件实际模型路径: models/SenseVoiceSmall/model.pt/SenseVoiceSmall.pt

cd /Users/bigemon/WorkSpace/xiaozhi-server

# 查看实际模型文件位置
ls -la models/SenseVoiceSmall/model.pt/
# 预期drwxr-xr-x  SenseVoiceSmall.pt或其他 .pt 文件)

# 移动到正确路径
PT_FILE=$(ls models/SenseVoiceSmall/model.pt/*.pt 2>/dev/null | head -1)
if [ -n "$PT_FILE" ]; then
    mv "$PT_FILE" models/SenseVoiceSmall/model.pt.file
    ln -sf model.pt.file models/SenseVoiceSmall/model.pt
    echo "✅ 模型文件已移动:$(basename $PT_FILE) → model.pt.file"
else
    echo "⚠️ 未找到 .pt 模型文件,请手动检查 models/SenseVoiceSmall/model.pt/"
fi

# 验证
ls -lh models/SenseVoiceSmall/

Step 5准备初始 .config.yaml

关键原则: manager-api.secret 先留空,等智控台启动后从页面获取再填入。

cd /Users/bigemon/WorkSpace/xiaozhi-server/data

cat > .config.yaml << 'EOF'
server:
  ip: 0.0.0.0
  port: 8000
  http_port: 8003
  # vision_explain: http://192.168.1.194:8003/mcp/vision/explain  # 全模块后由智控台管理

manager-api:
  url: http://xiaozhi-esp32-server-web:8002/xiaozhi
  secret: ""   # ← 先留空,智控台启动后从这里获取并填入

# MCP 接入点(保持不变)
mcp_endpoint: ws://mcp-endpoint-server:8004/mcp_endpoint/mcp/?token=usxQ%2BQ7GkvPsndgGVZDZBCE1%2Bcp6w1dJKkmoj7EJCqM%3D
EOF

echo "✅ .config.yaml 初始版本已创建"

Step 6停止现有单模块容器

# 停止并移除旧容器(约 1-3 秒服务中断)
docker stop xiaozhi-esp32-server && docker rm xiaozhi-esp32-server

echo "✅ 旧容器已清理"
echo "⚠️  ESP32 设备将在新容器启动后自动重连(端口不变)"

Step 7启动全模块 Docker Compose

cd /Users/bigemon/WorkSpace/xiaozhi-server

# 启动全部 4 个容器
docker compose -f docker-compose_all.yml up -d

# 确认 4 个容器都在运行
docker ps --format "{{.Names}}\t{{.Status}}" | grep xiaozhi

预期输出:

xiaozhi-esp32-server           Up
xiaozhi-esp32-server-web       Up
xiaozhi-esp32-server-db        Up (healthy)
xiaozhi-esp32-server-redis     Up (healthy)

Step 8等待 MySQL + Redis 健康检查

# 等待 MySQL 健康检查(最多 60 秒)
echo "等待 MySQL 就绪..."
for i in $(seq 1 20); do
  status=$(docker inspect --format='{{.State.Health.Status}}' xiaozhi-esp32-server-db 2>/dev/null)
  [ "$status" = "healthy" ] && echo "✅ MySQL 已就绪 (${i}0s)" && break
  echo "  尝试 ${i}/20状态: ${status:-starting}..."
  sleep 3
done

# 等待 Redis
echo "等待 Redis 就绪..."
for i in $(seq 1 10); do
  status=$(docker inspect --format='{{.State.Health.Status}}' xiaozhi-esp32-server-redis 2>/dev/null)
  [ "$status" = "healthy" ] && echo "✅ Redis 已就绪 (${i}0s)" && break
  echo "  尝试 ${i}/10状态: ${status:-starting}..."
  sleep 2
done

Step 9验证智控台启动成功

docker logs xiaozhi-esp32-server-web 2>&1 | tail -10

成功标志:

Started AdminApplication in 16.057 seconds (process running for 17.941)
http://localhost:8002/xiaozhi/doc.html

Step 10注册智控台管理员账号

用浏览器打开:http://127.0.0.1:8002

  1. 点击注册,创建第一个账号
  2. 第一个注册的账号自动成为超级管理员
  3. 超级管理员权限:模型管理、用户管理、参数配置

Step 11配置 server.secret

  1. 登录智控台 → 参数管理
  2. 找到 server.secret,复制参数值
  3. 填入 data/.config.yaml
# 将 SECRET_VALUE 替换为从智控台复制的值
sed -i '' "s|secret: \"\"|secret: \"YOUR_SECRET_VALUE\"|" \
  /Users/bigemon/WorkSpace/xiaozhi-server/data/.config.yaml

# 确认
grep "secret:" /Users/bigemon/WorkSpace/xiaozhi-server/data/.config.yaml

Step 12配置 MiniMax LLM

  1. 登录智控台 → 模型配置大语言模型
  2. 新增或修改 MiniMax 配置:
    • 类型:OpenAI 兼容
    • 模型名:MiniMax-M2.5MiniMax-M2.7
    • API 地址:https://api.minimaxi.com/v1
    • API KeyMiniMax Token Plan Key
  3. 保存

Step 13配置 MiniMax TTS如需

  1. 智控台 → 模型配置语音合成
  2. 选择 MinimaxTTS 或继续使用 EdgeTTS(免费无需 Key

Step 14配置 server.websocket 和 server.ota

全模块部署后ESP32 固件需要从智控台读取这两个地址。

  1. 登录智控台 → 参数管理
  2. 找到 server.websocket,填入:
    ws://192.168.1.194:8000/xiaozhi/v1/
    
  3. 找到 server.ota,填入:
    http://192.168.1.194:8002/xiaozhi/ota/
    

⚠️ OTA 端口是 8002(智控台),不是 8003

Step 15重启 server 容器

docker restart xiaozhi-esp32-server
docker logs -f xiaozhi-esp32-server 2>&1 | head -20

成功标志:

Websocket地址是 ws://192.168.1.194:8000/xiaozhi/v1/

Step 16验证 MiniMax LLM

# 测试玩偶对话(用修复后的 CLI
cd /Users/bigemon/WorkSpace/child-psycho-companion
source .venv/bin/activate
python xiaozhi_cli_client.py "你好"

观察日志中是否还有 401 错误。如成功,玩偶应正常回复。


4. 验证清单

验证项 命令/方法 成功标准
MySQL 健康 docker inspect xiaozhi-esp32-server-db -f '{{.State.Health.Status}}' healthy
Redis 健康 docker inspect xiaozhi-esp32-server-redis -f '{{.State.Health.Status}}' healthy
智控台 浏览器打开 http://127.0.0.1:8002 能注册/登录
MiniMax LLM python xiaozhi_cli_client.py "测试" 无 401 错误,玩偶回复
WS 服务 curl -s --max-time 3 http://127.0.0.1:8003/xiaozhi/v1/ 连接建立
MCP Endpoint docker logs xiaozhi-esp32-server 2>&1 | grep MCP 连接成功

5. 回滚步骤

情况 A全模块启动后 server 连接 manager-api 失败

# 1. 确认 secret 已正确填写
grep "secret:" /Users/bigemon/WorkSpace/xiaozhi-server/data/.config.yaml

# 2. 仅重启 server
docker restart xiaozhi-esp32-server
docker logs -f xiaozhi-esp32-server

情况 B完全回滚到单模块服务中断最小化

cd /Users/bigemon/WorkSpace/xiaozhi-server

# 停止全模块(保留 volume
docker compose -f docker-compose_all.yml stop

# 恢复旧单模块容器
docker run -d \
  --name xiaozhi-esp32-server \
  --restart always \
  --security-opt seccomp:unconfined \
  -e TZ=Asia/Shanghai \
  -p 8000:8000 -p 8003:8003 \
  -v /Users/bigemon/WorkSpace/xiaozhi-server/data:/opt/xiaozhi-esp32-server/data \
  ghcr.nju.edu.cn/xinnan-tech/xiaozhi-esp32-server:server_latest

# 恢复网络连接
docker network connect mcp-endpoint-server_default xiaozhi-esp32-server 2>/dev/null || true
docker network connect xiaozhi-server_default xiaozhi-esp32-server 2>/dev/null || true

echo "✅ 已回滚到单模块"

情况 C完全恢复保留 MySQL 数据)

cd /Users/bigemon/WorkSpace/xiaozhi-server

# 停止全模块(保留 MySQL 数据 volume
docker compose -f docker-compose_all.yml down

# 启动单模块
docker run -d \
  --name xiaozhi-esp32-server \
  --restart always \
  --security-opt seccomp:unconfined \
  -e TZ=Asia/Shanghai \
  -p 8000:8000 -p 8003:8003 \
  -v /Users/bigemon/WorkSpace/xiaozhi-server/data:/opt/xiaozhi-esp32-server/data \
  ghcr.nju.edu.cn/xinnan-tech/xiaozhi-esp32-server:server_latest

附录:已知问题与解决

问题 原因 解决
MySQL 启动慢 latest tag 构建不稳定 改用 mysql:8.0
FunASR 模型 404 volume 挂载期望文件,实际是目录 移动 .pt 文件到正确路径
LLM 401 manager-api 云端配置覆盖本地 全模块后由智控台管理
OTA 地址写错端口 单模块用 8003全模块用 8002 见 Step 14