CentOS 下部署支持 S3 的 Jellyfin

发布于:10/4/2024, 9:58:11 PM @孙博
技术分享 | jellyfin,s3,媒体服务器,dlna
许可协议:署名-非商业性使用(by-nc)

群晖于 2024-09-11 发布了 DS923+ 的系统更新 7.2.2-72806,并在更新说明中明确提到 将不再支持 Video Station。尽管这个软件本身做的也比较拉胯,但好歹也正常使用了许多年,现在忽然被废弃了,无论未来是否还会上架,但我都不会再信任群晖了,所以必须要想办法搞一个替代品。

经过一番研究,发现有 KodiEmbyPlexJellyfin 等多种成熟的产品可选,反正我都没用过,不存在所谓的信仰,根据一些评测博客的对比,我感觉 Jellyfin 相对来说更符合我对家庭媒体服务器的需求,所以就深入研究了一下。

由于我有自己的机柜,并部署了 S3 集群(基于 minio 搭建的 6 节点高可用集群),所以我希望能一劳永逸的将电影、动画等文件托管到 S3 中,但是遗憾的是,包括 Jellyfin 在内的大部分媒体服务器都只支持本地文件系统,所以只能先想办法将 S3 挂载到本地,然后再映射给 Jellyfin 使用了。

虽然我有一个 K3S 集群,但是为了防止对我的生产环境产生不稳定性隐患,我还是决定使用 CentOS 的虚拟机直接部署,而不是使用容器进行部署。


好在有 s3-fuse (https://github.com/s3fs-fuse/s3fs-fuse) 这个项目,只不过考虑到 CentOS 7 已经寿终正寝,所以比起预编译的二进制文件,我决定还是使用源码编译的方式来安装,看了下文档发现,s3fs-fuse 的项目真的是非常完善,稍微具备一点编程技巧的人,都能很容易理解如何通过源码完成部署。

我虚拟化的机器都是最小化安装的裸机,甚至连 wget 都没有的那种。所以首先是安装 gcc 等在内的依赖库:

yum install automake fuse-devel gcc-c++ git libcurl-devel libxml2-devel make openssl-devel -y

然后下载源码包:

git clone https://github.com/s3fs-fuse/s3fs-fuse.git

接着进入源码目录,并依次执行编译命令:

cd s3fs-fuse
./autogen.sh
./configure
make && make install

全部执行成功后,就可以通过 s3fs 命令来挂载 S3 文件系统了。

首先创建一个 /etc/passwd-s3fs 文件用来保存 S3 集群中提前配置好的密钥信息:

# 请将 YOUR_S3_ACCESS_KEY 和 YOUR_S3_SECRET_KEY 分别替换为你的密钥,对 Linux 运维并不是特别熟悉的朋友,建议不要使用含有符号的字符,以免出现错误。
echo "YOUR_S3_ACCESS_KEY:YOUR_S3_SECRET_KEY" > /etc/passwd-s3fs

然后给文件赋予读写权限:

chmod 600 /etc/passwd-s3fs

接着只需要执行如下命令即可挂载:

# 你需要将 /mnt/oss 替换为你想要挂载的目录,将 YOUR_BUCKET 替换为你的 S3 存储桶名称,将 YOUR_S3_ENDPOINT 替换为你的 S3 集群的域名。
mkdir -p /mnt/oss
s3fs YOUR_BUCKET /mnt/oss -o passwd_file=/etc/passwd-s3fs -o url=https://YOUR_S3_ENDPOINT -o use_path_request_style

当你执行到这里时,事实上就已经完成了文件系统的挂载了,你可以通过 df -h 查看挂载情况。至此,我们解决了存储的问题,下面就可以安装 jelllyfin 了。


在正式开始安装 jellyfin 前,我们又需要先处理因为讨厌的许可证之类的问题,而需要手动安装的 ffmpeg 了。

John Van Sickle 提供的预编译的 ffmpeg 的网站 (https://johnvansickle.com/ffmpeg/) 上,提供了很多版本的编译包,我这里使用的是 ffmpeg-release-amd64-static.tar.xz,将其下载并解压。

你可能需要下载与你的操作系统发行版匹配的版本,同时要注意的是,从这个网站下载文件非常的慢,有可能需要你采取一些魔法手段加速你的下载过程。

xz -d ffmpeg-release-amd64-static.tar.xz
tar -xvf ffmpeg-release-amd64-static.tar
mv -f ffmpeg-7.0.2-amd64-static/ /opt/ffmpeg/

编辑你的 ~/.bashrc 文件,并添加如下内容:
export PATH="/opt/ffmpeg:$PATH"

再执行 source ~/.bashrc 使之生效。便可以使用 ffmpeg 命令了:

[root@jellyfin ~]# ffmpeg -version
ffmpeg version 7.0.2-static https://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2024 the FFmpeg developers
built with gcc 8 (Debian 8.3.0-6)
configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp --enable-libgme --enable-gray --enable-libaom --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libdav1d --enable-libxvid --enable-libzvbi --enable-libzimg
libavutil      59.  8.100 / 59.  8.100
libavcodec     61.  3.100 / 61.  3.100
libavformat    61.  1.100 / 61.  1.100
libavdevice    61.  1.100 / 61.  1.100
libavfilter    10.  1.100 / 10.  1.100
libswscale      8.  1.100 /  8.  1.100
libswresample   5.  1.100 /  5.  1.100
libpostproc    58.  1.100 / 58.  1.100

下面我们就可以正式安装 jellyfin 了,找到官方为 CentOS 操作系统提供的安装包下载页面 (https://repo.jellyfin.org/?path=/server/centos/latest-stable/amd64),在这里我下载的是:jellyfin-10.8.13-1.el7.x86_64.rpmjellyfin-server-10.8.13-1.el7.x86_64.rpmjellyfin-web-10.8.13-1.el7.noarch.rpm。然后便可以很方便的使用 rpm 命令来安装:

rpm -Uvh --nodeps jellyfin-10.8.13-1.el7.x86_64.rpm jellyfin-server-10.8.13-1.el7.x86_64.rpm jellyfin-web-10.8.13-1.el7.noarch.rpm

将其设置为开机自动启动:

systemctl start jellyfin
systemctl enable jellyfin
systemctl status jellyfin

如果没有异常的话,安装到这里就成功了,下面可以打开 http://:8096/ 进行访问。

创建帐户之类的操作我想不需要额外赘述了,大家添加 存储库 的时候可能会遇到与我相同的问题:系统会提示我们没有 /mnt/oss 的访问权限,而这就很坑了,因为我们的目的就是创建一个能使用 S3 托管的 Jellyfin 媒体库,现在访问不了 S3 的文件,这该怎么办?

其实问题很简单,我们挂载 S3 时用的是 root 帐户,而 Jellyfin 默认是使用 jellyfin 帐户来运行,所以只需要将 /mnt/oss 的拥有者改为 jellyfin 即可。

通过查询 s3-fuse 的文档可以知道,s3fs 命令默认是以执行人的身份挂载文件系统的,所以我们有两种方法解决这个问题:

  1. 使用 s3fs 命令时添加 -o allow_other 选项,这样就可以以 jellyfin 帐户的身份挂载了;
  2. 使用 jellyfin 帐户来挂载,这样即便不改变挂载命令, jellyfin 帐户也可以直接拥有 /mnt/oss 的访问权限。

我在这里选择的是 <第 1 种> 方法,其实选择那个都无所谓。因为如果我们要考虑重启后仍然可以自动挂载,本来我们也需要再写一段命令解决这个问题,否则每次重启服务器还需要手动登陆进去挂载一次。

先创建一个文件:/etc/systemd/system/s3fs-mount.service,然后添加以下内容:

[Unit]
Description=Mount S3 bucket using s3fs
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/mount_s3fs.sh
RemainAfterExit=true

[Install]
WantedBy=multi-user.target

再创建一个 /usr/local/bin/mount_s3fs.sh,并添加如下内容:

#!/bin/bash

# 定义用户名和组名(调试用,非必须)
USERNAME=jellyfin
GROUPNAME=jellyfin

# 获取用户ID和组ID(调试用,非必须)
UID=$(id -u $USERNAME)
GID=$(id -g $GROUPNAME)

# 输出调试信息到日志文件(调试用,非必须)
echo "Executed by: $(whoami)" > /tmp/mount_s3fs.log
echo "Username: $USERNAME, UID: $UID" >> /tmp/mount_s3fs.log
echo "Groupname: $GROUPNAME, GID: $GID" >> /tmp/mount_s3fs.log

# 挂载命令(命令中的 uid 和 gid 需要你自己提前查出,通过 service 执行时有时候会取不到,故未做成 shell 变量)
/usr/local/bin/s3fs YOUR_BUCKET /mnt/oss -o passwd_file=/etc/passwd-s3fs -o url=https://YOUR_S3_ENDPOINT -o use_path_request_style -o uid=997 -o gid=995 -o allow_other

为新创建的文件添加执行权限:

chmod +x /usr/local/bin/mount_s3fs.sh

刷新下服务配置即可。

systemctl daemon-reload
systemctl enable s3fs-mount.service

但是不要着急重启,因为你还少配置了一个东西,就是为 jellyfin 指定 ffmpeg 的路径。
使用 vi 修改一下 /etc/sysconfig/jellyfin
[OPTIONAL] ffmpeg binary paths, overriding the UI-configured values 章节出增加如下配置:

JELLYFIN_FFMPEG_OPT="--ffmpeg=/opt/ffmpeg/ffmpeg"

保存后就可以 reboot 重启了。


稍作片刻,再次打开浏览器地址 http://:8096/。

恭喜你,你已经成功搭建了一个支持 S3 的 Jellyfin 媒体库了。

前一篇:从零开始搭建 3 主 ES 8 集群
后一篇:没有更多了