在 Linux 容器中部署 Jellyfin 并持久化媒体配置

在 Linux 容器中部署 Jellyfin 并持久化媒体配置

原作者:Jellyfin 文档贡献者。来源:Jellyfin 容器安装文档。本文译编官方容器、Docker / Compose、Podman、systemd 与硬件转码部分。源站标示 CC BY-ND 4.0;该许可说明的是原站内容,不作为本文改编稿的开放许可。本文译文及原创配图依据另行取得的授权使用。

Linux 主机通过持久配置卷、缓存卷和只读媒体挂载运行 Jellyfin;Rootless Podman、稳定镜像版本和可选转码设备构成部署边界。
原创部署关系图:媒体只读、配置持久化;不是实际运行截图。

Jellyfin 官方镜像以 Debian 为基础,由项目源码构建,发布在 Docker Hub 的 jellyfin/jellyfin 和 GitHub Container Registry 的 ghcr.io/jellyfin/jellyfin,支持多种架构。文档还列出 LinuxServer.io 与 hotio 等非官方镜像;本文配置选用官方镜像,第三方镜像维护者与打包基础不同。

镜像标签和支持平台

文档给出的标签规则:latest 跟随最新稳定版,包括主、次版本升级;10 指向 10.x 中最新版本;10.11 指向 10.11.x 最新版;10.11.0 固定一个发行版本;形如 10.11.0.20251020-004604 的标签固定某个打包构建。选择稳定部署时,固定版本比自动跟随 latest 更容易复现和回滚;升级前备份配置并读对应版本变更。

官方不支持把容器部署在 Windows 或 macOS 主机上,建议这些平台原生安装。部分功能已知会异常,包括硬件转码,以及 macOS 上 Docker 的媒体扫描。本文范围是 Linux 容器。

持久化配置、缓存与媒体路径

Jellyfin 的配置数据库和元数据放在容器的 /config,转码缓存放在 /cache。删除容器不应删除这些持久数据。Docker 可用宿主机目录 bind mount,也可用 Docker volume:

mkdir -p /srv/jellyfin/config /srv/jellyfin/cache
docker volume create jellyfin-config
docker volume create jellyfin-cache

上面四行是两种存储方案的示意:bind mount 用宿主目录;named volume 则只需保留 volume,不需要同时再建对应目录。简单部署常用 bind mount,便于备份和外部工具管理;Docker volume 便于由容器运行时管理。无论选择哪种,都需要备份配置、理解卷实际位置与权限,缓存通常可重建,但应按实际工作负载预留容量。

Docker 命令行部署

文档的命令模式是挂载配置、缓存和媒体目录,发布服务端口,并可选指定容器 UID/GID。桥接网络是 Docker 的默认值;host 网络可选,但 DLNA 发现需要它。默认 HTTP 服务使用 TCP 8096,局域网自动发现用 UDP 7359。打开对外防火墙端口会扩大可访问范围,应仅开放实际需要的网络区域。

下面给出便于审阅的单条命令示例,需先把路径、UID/GID 与镜像标签换成环境中确认的值。命令只运行容器,不会自动创建宿主路径:

docker run -d --name jellyfin \
  --user 1000:1000 \
  --publish 8096:8096/tcp \
  --publish 7359:7359/udp \
  --volume /srv/jellyfin/config:/config \
  --volume /srv/jellyfin/cache:/cache \
  --mount type=bind,source=/srv/media,target=/media,readonly \
  --restart=unless-stopped \
  jellyfin/jellyfin:latest

这是编辑整理的示意,保留 latest 只是展示官方源教程所列标签;实际稳定部署应按升级策略选择明确版本。示例使用 UID/GID 1000:1000,宿主机目录必须授权该身份访问。若采用 host 网络,需调整端口发布参数,并注意暴露的接口和发现范围。

Docker Compose 及额外媒体挂载

配置多个媒体目录时可以分别挂载到不同容器路径,并将不需要写入的媒体目录设为只读。服务器字幕烧录需要字体时,可只读挂载自定义字体目录到 /usr/local/share/fonts/custom;也可挂载备用字体并在 Jellyfin 设置中把目录设为 /fallback_fonts。原文 Compose 示例还包含自动发现服务地址环境变量 JELLYFIN_PublishedServerUrl,以及 host 网络健康检查可能需要的 host.docker.internal:host-gateway 主机映射。这些选项按部署情形使用,而不是全部必需。

services:
  jellyfin:
    image: jellyfin/jellyfin:latest
    container_name: jellyfin
    user: "1000:1000"
    ports:
      - "8096:8096/tcp"
      - "7359:7359/udp"
    volumes:
      - /srv/jellyfin/config:/config
      - /srv/jellyfin/cache:/cache
      - type: bind
        source: /srv/media
        target: /media
        read_only: true
    restart: unless-stopped

保存为 docker-compose.yml 后,源文用 docker compose up 启动,添加 -d 可后台运行。Compose YAML 中镜像标签示例仍是可变的 latest;用于固定升级节奏时,应填入经过审核的发布版本,不要仅依赖此示意文件。

代码审查发现原命令块存在复制风险。源文 CLI 示例把注释放在反斜杠续行之后,例如“--volume /config ”下一行是“# Alternatively ...”。POSIX shell 会先移除反斜杠换行,再把 # 当成行内注释,可能注释掉命令余部并导致容器命令不完整。上文整理后的命令删除了这些夹在续行中的注释;不要把原始 CLI 块原样粘贴运行。

Podman:Rootless 容器与卷标签

Podman 支持 rootless 容器,Jellyfin 文档建议使用这一方式,并在容器内以非 root 用户运行。源页按 Fedora 展示 sudo dnf install -y podman。rootless 示例:

podman run \
  --detach \
  --label "io.containers.autoupdate=registry" \
  --name myjellyfin \
  --publish 8096:8096/tcp \
  --publish 7359:7359/udp \
  --user "$(id -u):$(id -g)" \
  --userns keep-id \
  --volume jellyfin-cache:/cache:Z \
  --volume jellyfin-config:/config:Z \
  --mount type=bind,source=/srv/media,destination=/media,ro=true,relabel=private \
  docker.io/jellyfin/jellyfin:latest

--user 指定容器身份,--userns keep-id 将当前用户 ID 映射进容器,帮助保持 bind mount 权限一致。SELinux 主机上的 :Z 或 relabel=private 为容器卷做私有标记;若需要共享,需按实际容器共享场景使用对应的 shared 标记,不应不加区别地修改主机策略。

上述 io.containers.autoupdate=registry 标签允许 podman auto-update 更新镜像。自动更新意味着镜像可在没有手工版本审核的情况下变化,文档提醒需有备份以恢复到先前状态。生产环境要明确升级与回滚流程,不能把“自动更新”视为自动安全。

Rootless Podman 的 systemd 用户服务

文档采用 Quadlet 风格的 jellyfin.container 文件,以 systemd 用户服务管理容器。为让用户登出后服务仍运行,源页先创建 jellyfin 用户并启用 linger,再切到该账户会话。示例文件存于该用户的 ~/.config/containers/systemd/jellyfin.container:

[Unit]
Description=jellyfin

[Container]
Image=docker.io/jellyfin/jellyfin:latest
AutoUpdate=registry
PublishPort=8096:8096/tcp
UserNS=keep-id
Volume=jellyfin-config:/config:Z
Volume=jellyfin-cache:/cache:Z
Volume=jellyfin-media:/media:Z

[Service]
SuccessExitStatus=0 143

[Install]
WantedBy=default.target

随后运行 systemctl --user daemon-reload 并启动 jellyfin 服务;启用 Podman 自动更新定时器的示例是 systemctl --user enable --now podman-auto-update.timer。检查日志用 journalctl --user -u jellyfin。用户创建、linger、服务重载和启动都会改变系统状态;本稿只作静态审查,不执行。

硬件加速转码

若要用 GPU 硬件转码,容器必须获准访问主机渲染设备。在较新 container-selinux(源文写 2.226 起)中,示例设置 SELinux 布尔项:

sudo setsebool -P container_use_dri_devices 1

-P 会持久化 SELinux 布尔值。如果是旧版,源文给出在容器参数中添加 --security-opt label=disable 的方法;这会关闭该容器的 SELinux 标签隔离,权限影响明显,不能作为通用默认设置。随后需将宿主机 /dev/dri 设备映射进容器,并确认显卡驱动、设备组和 Jellyfin 转码配置匹配。仅当硬件和安全策略都明确需要时,才开放设备。

源文也给出 Podman CLI 与 systemd 配置示例:CLI 增加 --device /dev/dri/:/dev/dri/;Quadlet 中用 AddDevice=/dev/dri/:/dev/dri/。旧 SELinux 版本才需考虑 SecurityLabelDisable=true。不同 GPU 厂商还可能需要额外步骤,应参考 Jellyfin 的硬件加速说明。

上线前的权限和版本边界

  • 配置与缓存分离保存;备份配置卷。媒体库默认只读挂载可避免服务误改原始媒体。
  • 按最小网络范围开放端口;DLNA 要求 host 网络时,也要评估主机网络暴露面。
  • 容器身份与宿主卷权限需相互匹配;rootless Podman 与 keep-id 通常比以 root 运行更安全。
  • 固定和记录镜像版本;自动更新前确保备份和回滚策略可用。
  • 容器硬件加速需要直通设备,会扩大容器权限。只加入实际需要的渲染节点,避免为方便而关闭 SELinux 隔离。

来源:Jellyfin 官方文档贡献者,《Container》。原站内容许可为 CC BY-ND 4.0;本文译文及原创配图依据另行取得的授权使用,不以原站许可表示本文改编稿开放授权。原文 Docker CLI 注释换行问题已在示例整理中修正并说明。容器升级、用户创建、防火墙、SELinux 和设备直通命令均未执行。版本标签是源文示例值,不构成当前稳定版声明。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容