【避坑】群晖 Docker 部署 IPTV 服务,这 10 个坑我全踩过了

从昨晚折腾到现在,能踩的坑基本都踩了一遍。 把这些列出来,希望后面的人别再重复踩。


一、Docker 镜像拉取相关

坑 1:把镜像加速器域名写在 compose 的 image 字段

错误写法:

image: docker.mirrors.ustc.edu.cn/guovin/iptv-api:latest

结果: 报 lookup 错误,DNS 解析失败。

正确做法: 镜像加速器是 Container Manager 全局设置,在【设置 → Docker】里填写,不能写在 yaml 的 image 名称里。image 字段就老老实实写原始镜像名。


坑 2:context deadline exceeded

现象: 拉镜像一直转圈,最后报这个错。

意思: 群晖 Docker 访问 Docker Hub 超时,网络层面拉不到海外镜像。

解决: 先配好国内镜像加速器,再拉取。反复重试基本没用。


二、xTeVe 配置相关

坑 3:以为滤波器选了频道就够了

错误认知: 在滤波器里选了 39 个卫视频道,以为 M3U 里就会有这 39 个台。

事实: 滤波器只是筛选候选频道。必须在【制图】页面勾选启用频道、分配频道号,才会真正导出到 M3U。

光在滤波器里选,M3U 还是只有一行 #EXTM3U。


坑 4:看 File Station 里的 xteve.m3u 文件大小判断输出

错误做法: 进 File Station 看 xteve.m3u 文件是 100 字节还是几 KB,以为这就是输出内容。

事实: xTeVe 的 /m3u 接口是实时动态生成的,根本不读取磁盘上的这个文件。 磁盘上那个小文件只是占位空文件,HTTP 接口返回什么和它没关系。


坑 5:以为 xTeVe 有一键重定向开关

错误认知: 以为 xTeVe 可以设置成"重定向模式",直接返回原始流地址,不用容器转发。

事实: xTeVe 2.2.0 没有这个开关。所有流地址都是 http://NASIP:34400/stream/xxx 形式,所有请求都必须经过 xTeVe 容器。


坑 6:浏览器直接打开 M3U 链接看内容

现象: 在浏览器输入 m3u 地址,以为页面会显示频道列表。

实际: xTeVe 的 M3U 接口响应头带 Content-Disposition: attachment,浏览器直接下载文件,不会在页面预览。

正确做法: 下载后用记事本打开看内容。


三、Jellyfin 接入相关

坑 7:HDHomeRun 地址带 http:// 前缀

错误写法:

http://192.168.0.51:34400

正确写法:

192.168.0.51:34400

带了 http:// 就会发现失败,这是 Jellyfin HDHomeRun 接入的经典坑。


坑 8:Jellyfin 容器访问不到 xTeVe

现象: 电脑浏览器能打开 xTeVe 的地址,但 Jellyfin 里就是扫不到频道。

原因: 群晖 Docker 默认 bridge 网络模式下,容器之间无法直接访问宿主机内网 IP。

解决:

  • 方案 A:两个容器都改成 host 网络模式
  • 方案 B:新建自定义 docker 桥接网络,把两个容器加进去

验证方法: 进 Jellyfin 容器终端执行 curl http://192.168.0.51:34400/m3u/xteve.m3u,能返回 m3u 文本说明网络正常,超时就是网络隔离问题。


四、其他常见错误认知

坑 9:TVHeadend 支持光盘刻录

错。TVHeadend 的录制是把直播节目流保存成视频文件到硬盘,俗称"录台"。 不是光盘刻录。


坑 10:Guovin IPTV-API 是流代理

错。Guovin 只负责抓取、测速、过滤 M3U 源,输出干净的 m3u 文件。 它不转发视频流,播放器还是直接访问原始源地址。

这也是它比 xTeVe 稳的原因——没有中间转发层。


写在最后

折腾了一整晚,最大的感悟就是:别过度设计。 只是想在 Jellyfin 里看电视,直接 M3U 直连就完了,别碰 xTeVe 这种中间层。 中间层越多,出问题的地方就越多,排查起来越费劲。