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

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 隔离。











暂无评论内容