返回首页

基于 Docker 的家庭媒体服务器:Transmission + Jellyfin + Telegram

基于 Docker 创建家庭媒体服务器指南,集成 Transmission、Jellyfin 和 Telegram Bot。支持 NAS、自动下载和通知。

一晚构建自己的 Netflix:Docker、Transmission、Jellyfin 和 Telegram Bot
Advertisement 728x90

# 在 Docker 中搭建家庭媒体服务器:Transmission、Jellyfin 和 Telegram 机器人

只需一个晚上,你就能组装出一个功能齐全的家庭媒体服务器,并配备便捷的 Telegram 控制。抛弃 Transmission 过时的界面,换用现代的 Flood UI;跳过手动复制文件,利用 Jellyfin 的自动索引;不再需要持续监控,直接在你的消息应用中收到下载完成通知。一切都运行在网络附加存储 (NAS) 上,只需一条 Docker 命令即可启动。

基于 Docker 的解决方案架构

系统的核心是三个容器,它们通过 CIFS 卷共享通用文件系统。Transmission 负责 torrent 下载,Jellyfin 索引媒体文件并提供观看界面,而 Telegram 机器人则作为控制和通知的用户界面。关键特性是使用带有 CIFS 驱动的 Docker 卷,从而允许在容器内直接挂载网络共享,而无需绑定到主机本地文件系统。

新手常见错误是试图在 Windows 上为网络驱动使用 bind 挂载。由于 WSL2 的特性,此类路径在容器内不可见。解决方案是明确指定卷类型为 cifs,并附带连接参数:

Google AdInline article slot
volumes:
  downloads:
    driver: local
    driver_opts:
      type: cifs
      device: ${SMB_HOST}
      o: "username=${SMB_USER},password=${SMB_PASSWORD},vers=3.0,uid=1000,gid=1000,file_mode=0777,dir_mode=0777"

Transmission 和 Jellyfin 这两个服务都使用此卷,但容器内的挂载点不同,从而确保路径一致且无冲突。

设置 Telegram 机器人和自动化

机器人使用 python-telegram-bot 库以 Python 编写,通过 Transmission 的 RPC API 与其交互。它以共享网络栈模式运行于 Transmission 容器(network_mode: "service:transmission"),从而省去额外端口转发并最小化延迟。

机器人主要功能:

Google AdInline article slot
  • 通过发送 .torrent 文件或磁力链接添加 torrent
  • 自动完成通知,附带 Unicode 进度条
  • 通过内联消息按钮管理活跃下载
  • 通知过滤,避免重启时重复发送

进度条通过简单函数实现:

def progress_bar(pct, width=12):
    filled = round(pct * width)
    return "█" * filled + "░" * (width - filled)

为避免机器人重启时发送垃圾消息,它会按 ID 跟踪已完成 torrent。启动时,脚本初始化 completed_ids 集合,仅对新完成的下载发送通知。

微调 Transmission 并绕过图片限制

官方 linuxserver/transmission 镜像有个怪癖:每次启动都会覆盖 settings.json 的部分内容,忽略环境变量。这会影响 watch-dirdownload-dirincomplete-dir 等设置。解决方案是使用 custom-cont-init.d 机制,它会在初始化后但守护进程启动前运行自定义脚本。

Google AdInline article slot

示例脚本 01-fix-settings.sh

#!/bin/sh
mkdir -p /downloads/Downloads
mkdir -p /downloads/.incomplete
mkdir -p /downloads/watch

SETTINGS=/config/settings.json
if [ -f "$SETTINGS" ]; then
    sed -i 's|"watch-dir": ".*"|"watch-dir": "/downloads/watch"|' $SETTINGS
    sed -i 's|"watch-dir-enabled": false|"watch-dir-enabled": true|' $SETTINGS
    sed -i 's|"download-dir": ".*"|"download-dir": "/downloads/Downloads"|' $SETTINGS
    sed -i 's|"incomplete-dir": ".*"|"incomplete-dir": "/downloads/.incomplete"|' $SETTINGS
    sed -i 's|"incomplete-dir-enabled": false|"incomplete-dir-enabled": true|' $SETTINGS
fi

另一个问题是安装 Flood UI。新版镜像移除了第三方界面。你需要手动从 GitHub 下载存档并解压到 config/flood-ui/。仓库中包含 setup-flood.sh 脚本用于自动化。

Jellyfin 首次启动与电视集成

启动容器后,打开 Jellyfin 网页界面 http://localhost:8096。初始设置包括创建用户并添加媒体库。将源指向 /media/Downloads——这就是 Jellyfin 容器中共享文件夹的挂载方式。

Jellyfin 会自动:

  • 扫描文件夹内容
  • 识别内容类型(电影、电视剧)
  • 从 TMDB 获取元数据和海报
  • 按流派、年份、演员构建直观导航

用于电视观看,安装官方 Jellyfin 应用(支持 Android TV、Apple TV、Fire TV、Roku)。首次启动时,输入主机的本地 IP 和端口 8096。用之前创建的用户登录。

常见问题与功能扩展

没有 NAS?将 CIFS 卷替换为本地文件夹,使用 bind 选项:

volumes:
  downloads:
    driver: local
    driver_opts:
      type: none
      device: /absolute/path/to/folder
      o: bind

想要 VPN?使用 gluetun 容器,并将 Transmission 移至其网络命名空间:

transmission:
  network_mode: "service:gluetun"
  depends_on:
    - gluetun

如何更新?运行:

docker compose pull && docker compose up -d

远程访问?使用 Tailscale 或 Cloudflare Tunnel——比路由器端口转发更安全。

关键要点

  • 对于 Windows 上的 Docker Desktop 中的网络驱动,CIFS 卷优于 bind 挂载至关重要
  • custom-cont-init.d 机制绕过了官方 Transmission 镜像限制
  • 机器人与 Transmission 间的共享网络栈简化了设置并提升了可靠性
  • Jellyfin 自动为媒体补充元数据——无需手动调整
  • 所有数据存于外部 NAS,使系统免于操作系统重装影响

— Editorial Team

Advertisement 728x90

继续阅读