Docker を使って自動更新される IPTV プレイリストサービスをデプロイする

プレイリストが数十チャンネルを超えると、手作業でのメンテナンスは現実的ではなくなる。チャンネル名を1つ変更するにはファイルを編集する必要があり、新しいデバイスを1台追加するには再度インポートする必要がある。Docker で軽量なプレイリストサービスを動かせば、NAS が定期的に生成し、固定アドレスで公開できるようになり、家のすべてのプレイヤーがこの1つのアドレスから取得できる。

この記事ではデプロイの考え方と Compose の書き方を説明する。ソースには自分が使用する権利を持つもの(事業者が配信するマルチキャストアドレス、自前ソース)を使う。

一、全体方針

  1. ソース一覧(チャンネル名 + アドレス)を入力として、NAS の1つのディレクトリに置く;
  2. container で定期的に「検出 + m3u 生成」を実行する;
  3. 生成された m3u を1つの Web port で外部に提供し、プレイヤーはこの URL を直接入力する;
  4. container は検出結果とログもディスクに保存し、後から追跡できるようにする。

二、ディレクトリ準備

まず NAS 上にディレクトリ構造を作成し、container に入力と出力の両方を mount する:

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

入力ファイル形式自分で簡潔に決めてよい。1行に1チャンネル:

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. ソース一覧を変更したら container を1回再起動するか、定期タスクが定刻に自動生成するのを待つ;
  4. 生成された m3u は Jellyfin / Emby / Plex の IPTV プラグインから直接読み込める。番組表は別途 XMLTV アドレスを設定すればよい。

五、実践上の要点

  • 同時実行数を大きくしない:一度に100以上のアドレスへ接続を開始すると、家庭用 router が簡単に飽和し、かえって大量の誤判定を招く。
  • 結果をバージョン管理する:毎日生成されるファイルを日付付きで1部保存し、問題発生時にどの日から変わったかを比較できるようにする。
  • ログを十分に残すcontainerログはトラブルシュート時のみ有用なので、ファイルへ出力し、単一ファイルのサイズを制限して、NASがいっぱいになるのを避けることを推奨する。
  • インターネットにportを公開しない。このサービスは家庭内専用なので、portをインターネットへマッピングしない;外部アクセスが本当に必要な場合はVPN経由で戻し、直接公開しない。
  • 内部ネットワークIPを固定する。NASに静的アドレスまたはDHCPリザベーションを設定する。そうしないとIPが変わった時点で、すべてのプレーヤーを変更する必要がある。

六、よくある問題

containerは起動したがm3uが空 まずログで入力ファイルが読み込まれているかを確認し、次にソースリストの区切り文字とエンコーディングに問題がないことを確認する。
チェック結果がすべて失敗となる まずcontainerが所属するネットワークからマルチキャストにアクセスできるかを確認する(多くのデフォルトbridgeネットワークでは不可)。hostネットワークモードに変更して試す。
プレーヤーにアドレスが無効と表示される URLをコンピューター上でVLCで開いて一度確認し、サービス側の問題かプレーヤー側の問題かを切り分ける。
定期タスクがトリガーされない containerのタイムゾーン設定を確認する。CRONはcontainerの時刻で動作する。

まとめ

containerで「チェック + 生成 + 配布」をつなげることで、プレイリストの保守は「手作業でファイルを編集する」から「ソースリストを一行変更し、残りは定期タスクに任せる」へと変わる。このフローの価値は、あなたが自分に使用権のあるソースを統一的に管理することにある——ソースの数は多くないが、制御可能で保守可能、ロールバック可能であることが、長期的に運用し続ける鍵だ。

THE END