🌈

“本以为三分钟搞定,结果三小时都在填坑——容器网络的水比想象中深”

1 项目背景

我在 Windows + WSL2 的Ubuntu 22.04 环境下

用 Docker 完整部署了开源项目 小智后端服务(替代官方服务 https://xiaozhi.me)。部署成功日志如下:

关键目标:将自建服务与 ESP32 智能语音硬件对接,实现 OTA(Over-The-Air)固件更新和 WebSocket 通信。


2 连环坑:从网络穿透到容器ip

2.1 第一坑:容器内网地址的“见光死”

容器启动日志显示 OTA 地址为 http://172.21.0.5:8003/xiaozhi/ota/(Docker 内部 IP):

当我在 ESP32 填入该地址时

// ESP32 终端报错
WS: Connecting to ws://172.21.0.2:8000/xiaozhi/v1/
TcpTransport: Failed to connect to 172.21.0.2:8000
WebSocket: Failed to connect to server

此时我认为问题可能出现在填入的容器内部的地址,导致外部的网络不可访问,
所以我将这个地址通过内网穿透向公网转发了出去,
于是就得到了下面的地址
在小智端填入的ota地址为:
https://ota.dolphinai.online/xiaozhi/ota/ 

结果是一样的,都是接不上服务器,怀疑是因为ota地址的原因
于是在浏览器测试了一下
发现接口是正常的,但是发送的地址可能有问题

发送的这个地址只能本地访问,这个172.21.0.2这个ip地址为docker内的ip地址容易变,如何将它固定,或者直接发送的是一个固定不暴露ip的地址比如api.dolphinai.online 小智硬件端终端的调试日志发现问题就是访问ws地址失败

问题本质172.21.0.x 是 Docker 内部动态 IP(bridge 网络),外部设备根本无法访问!


2.2 第二坑:frp 穿透后的地址错配

我通过 frp 内网穿透(参见教程《使用docker部署frpc》)将服务暴露到公网:

  • 公网 OTA 地址:https://ota.dolphinai.online/xiaozhi/ota/
  • 公网 WebSocket 地址:ws://api.dolphinai.online/xiaozhi/v1/

但 ESP32 仍然报错
通过浏览器测试 OTA 接口返回的内容发现致命问题:

{
  "websocket": {
    "url": "ws://172.21.0.2:8000/xiaozhi/v1/" // 返回的还是内部IP!
  }
}

症结所在:后端服务在 Docker 容器内运行,返回的 WebSocket 地址是容器内部 IP,即使 OTA 接口本身能被公网访问。
 

所以现在先解决两个问题
1.docker容器的ip地址变化导致的连接不上ws的地址 先重启容器,再固定容器ip地址,再修改frpc的地址,再来测试看看是不是因为地址变化导致的连接不上

2.通过ota发送的ws地址是一个本机地址 ,不能作为在线远程固件的连接使用,需要修改代码,直接修改ota发送的地址为一个服务器ip的地址


2.3 第三坑:被忽略的官方文档

正当我开始准备将这两个问题都走一遍的时候, 我又想着先去官网再看看教程,看了一遍其中写的ota的地址写得很明白官方文档,发现关键提示:

🌈

OTA 端口应为 8002,而非容器日志中的 8003!

测试 http://服务器IP:8002/xiaozhi/ota/ 返回正确响应:

{
  "websocket": {
    "url": "ws://43.134.41.208:8000/xiaozhi/v1/" // 公网IP!
  }
}

OTA检查结果: 这次将这个公网的地址发送出来了,说明可以进行连接了

{"server_time":{"timestamp":1751193611211,"timeZone":"Asia/Shanghai","timezone_offset":480},"activation":{"code":"182071","message":"https://xiaozhi.dolphinai.online/\n182071","challenge":"34:4F:9D:CA:C4:49"},"firmware":{"version":"1.0.0","url":"http://xiaozhi.server.com:8002/xiaozhi/otaMag/download/NOT_ACTIVATED_FIRMWARE_THIS_IS_A_INVALID_URL"},"websocket":{"url":"ws://43.134.41.208:8000/xiaozhi/v1/"}}

说明测试成功,这次可以再次进行配置了


3 设备对接成功的关键步骤

3.1 重刷 ESP32 固件

使用在线烧录工具更新固件:

3.2 配置设备网络

  1. 连接 ESP32 热点 http://192.168.4.1
  2. 高级配置 填入正确 OTA 地址:
    http://你的公网IP:8002/xiaozhi/ota/
  3. 保存后切换至家庭WiFi

3.3 绑定智能体

设备连接成功后显示 6 位激活码,在前端创建智能体并绑定:
 


4 血泪总结

错误点 正确做法 代价
信任容器日志端口 以官网文档端口为准 3小时调试
未校验OTA返回内容 手动调用接口验证返回值 2次重刷固件

附录

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐