用 Docker 部署自动更新的 IPTV 播放列表服务

播放列表一旦超过几十个频道,手工维护就不现实了:改一个频道名要编辑文件,加一台上新设备又要重新导入。用 Docker 跑一个轻量的播放列表服务,可以让 NAS 定时生成并对外提供一个固定地址,家里所有播放器都从这一个地址拉取。

这篇讲部署思路和 Compose 写法,源使用你自己有权使用的那些(运营商下发的组播地址、自建源)。

一、整体思路

  1. 把源清单(频道名 + 地址)作为输入,放在 NAS 的一个目录里;
  2. 用容器定时执行「检测 + 生成 m3u」;
  3. 生成的 m3u 通过一个 Web 端口对外提供,播放器直接填这个 URL;
  4. 容器把检测结果与日志也落盘,方便回溯。

二、目录准备

先在 NAS 上建好目录结构,容器把输入与输出都挂进去:

docker/
└── iptv/
    ├── data/          # 输出:生成的 m3u、日志
    │   └── playlist.m3u
    ├── source.txt     # 输入:你自己的频道清单
    └── docker-compose.yml

输入文件格式自己定简单一点即可,一行一个频道:

CCTV-1 综合|udp://@239.x.x.x:1234
湖南卫视|rtp://239.x.x.x:5678

三、docker-compose.yml

services:
  iptv:
    image: <你选用的镜像>
    container_name: iptv
    restart: unless-stopped
    ports:
      - "50086:50086"
    volumes:
      - ./data:/app/data
      - ./source.txt:/app/source.txt:ro
    environment:
      - TZ=Asia/Shanghai
      - CHECK_TIMEOUT=5          # 单个地址检测超时(秒)
      - CHECK_CONCURRENCY=8      # 并发数,别设太大
      - CRON=0 4 * * *           # 每天凌晨 4 点跑一次

启动:

docker compose up -d
docker compose logs -f      # 观察首次生成的输出

四、验证与使用

  1. 浏览器访问 http://你的NAS_IP:50086/playlist.m3u,能看到内容说明服务正常;
  2. 在播放器里「添加源 → 从 URL 导入」,填上面这个地址;
  3. 改动源清单后重启一次容器,或等定时任务到点自动生成;
  4. 生成的 m3u 可以直接被 Jellyfin / Emby / Plex 的 IPTV 插件读取,节目单另配 XMLTV 地址即可。

五、几个实践要点

  • 并发别开大:一次性对上百个地址发起连接,家用路由器很容易被打满,反而导致大量误判。
  • 结果要版本化:每天生成的文件带日期保留一份,出问题能对比是哪天开始变的。
  • 日志留够:容器日志只在排查时有用,建议输出到文件并限制单文件大小,避免把 NAS 写满。
  • 不要对外网开放端口:这个服务只给家里用,端口不要映射到公网;确实需要外部访问时,走 VPN 回来,不要直接暴露。
  • 固定内网 IP:给 NAS 配一个静态地址或 DHCP 保留,否则 IP 一变,所有播放器都要改。

六、常见问题

容器起来了但 m3u 是空的 先看日志里输入文件是否被读到;再确认源清单的分隔符与编码没问题。
检测结果全是失败 先确认容器所在网络能否访问组播(多数默认桥接网络不行),改用 host 网络模式试试。
播放器提示地址无效 把 URL 拿到电脑上用 VLC 打开验证一次,区分是服务问题还是播放器问题。
定时任务没触发 检查容器时区设置,CRON 是按容器时间走的。

小结

用容器把「检测 + 生成 + 分发」串起来,播放列表维护就从「手工编辑文件」变成了「改一行源清单、剩下的交给定时任务」。这套流程的价值在于你对自己有权使用的源做统一管理——源的数量不多,但可控、可维护、可回滚,这才是长期跑下去的关键。

THE END