Alain's Blog

  1. 首页
  2. 虚拟机
  3. Proxmox VE
  4. 正文

Proxmox VE(PVE) 7.x中,使用LXC安装Jellyfin,开启硬解码等

2022年8月9日 17150点热度 13人点赞 9条评论

Proxmox VE(PVE) 7.x下,LXC中安装Jellyfin,开启硬解等

转载请注明出处,本文仅用于学习交流,不对之处,恳请指正 ,部分图片摘取网络,如有侵权请联系

Proxmox VE(PVE) 7.x中,使用Ubuntu LXC安装Jellyfiy,并开启硬解码,直通网卡,修复Ubuntu中文乱码,修复Jellyfin中文显示框框,开启https,挂载NAS网络磁盘等,也解决了群晖没有部分核显驱动的问题

前因

为什么选择用LXC来部署Jellyfin,而非在NAS虚拟机中部署Jellyfin?

  1. Intel GPU很多都支持虚拟化,可供多个虚拟机或者LXC使用,故不使用直通的方式。
  2. 我的NAS并没有用到硬转码的功能
  3. 我的核显型号是P630,在NAS系统中安装驱动相对麻烦

使用LXC安装Ubuntu 22.04系统

  1. 先在CT Templates中下载对应的系统模板,这里我使用的是最新的 Ubuntu-22.04-standard

    使用LXC安装Ubuntu 22.04系统

  2. 在对应的宿主机节点上右键创建CT(LXC),根据提示一步步完成即可,其中应该注意的是,我们需要取消选中非特权容器的按钮,以便访问宿主机的显卡或者开启SMB的功能,其他步骤就不再赘述。

    使用LXC安装Ubuntu 22.04系统

  3. 根据提示完成安装后,启动LXC容器,并进入容器中

    1. 更新源

      apt-get update
    2. 更新软件

      apt-get dist-upgrade

Proxmox VE(PVE) 7.x 下,LXC"直通"核显

宿主机中操作

  1. 关闭LXC容器

  2. 获取显卡文件ID

    ls -l /dev/dri/
    # drwxr-xr-x 2 root root         80 Jul 14 01:29 by-path
    # crw-rw---- 1 root video  226,   0 Dec 29 11:20 card0
    # crw-rw---- 1 root render 226, 128 Jul 14 01:29 renderD128
  3. 修改LXC容器配置映射显卡

    编辑对应的LXC配置文件,如 nano /etc/pve/lxc/101.conf,将上面查询到的ID写入到配置文件中

    # Proxmox VE(PVE) 6.x
    # lxc.cgroup.devices.allow: c 226:0 rwm
    # lxc.cgroup.devices.allow: c 226:128 rwm
    # Proxmox VE(PVE) 7.x
    lxc.cgroup2.devices.allow: c 226:0 rwm
    lxc.cgroup2.devices.allow: c 226:128 rwm
    lxc.autodev: 1
    lxc.hook.autodev: /var/lib/lxc/101/mount_hook.sh
    # lxc.mount.entry: /dev/dri/card0 dev/dri/card0 none bind,optional,create=file
    # lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file
  4. 编写mount_hook脚本

    nano /var/lib/lxc/101/mount_hook.sh

    写入以下代码

    mkdir -p ${LXC_ROOTFS_MOUNT}/dev/dri
    mknod -m 666 ${LXC_ROOTFS_MOUNT}/dev/dri/card0 c 226 0
    mknod -m 666 ${LXC_ROOTFS_MOUNT}/dev/dri/renderD128 c 226 128

    修改脚本权限为可执行

    chmod +x /var/lib/lxc/101/mount_hook.sh

(可选) Proxmox VE(PVE) 7.x下, LXC"直通"网卡

宿主机中操作

如果你没有特定的硬件网卡需要绑定可以跳过此步骤。!!!如果你有绑定网卡的需求,需要在桥接网卡下,最少启动过LXC容器一次!!!

  1. 因为视频播放占用的流量较大,使用桥接网卡可能会导致占用过多性能,我们可以通过以下方式绑定特定的网卡。

    lxc.net.0.type: phys
    lxc.net.0.link: enp7s0f0
    lxc.net.0.ipv4.address: 192.168.1.101/24
    lxc.net.0.ipv4.gateway: 192.168.1.100
    lxc.net.0.flags: up
  2. 删除原先的桥接网卡

    我们可以选择在Proxmox的管理页面删除,也可以在配置文件中删除。

    删除原先的桥接网卡

  3. 启动LXC容器并测试网卡是否可用

    ping 114.114.114.114

解决LXC容器内Ubuntu Server 22.04显示中文乱码问题

编辑/etc/default/locale文件

nano /etc/default/locale

修改为以下内容

LANG="en_US.UTF-8"
LANGUAGE="en_US:en"

修改Linux的时区

查看当前设置的时区

timedatectl

列出所有可用时区

timedatectl list-timezones

设置时区为上海时区

timedatectl set-timezone Asia/Shanghai

开启NTP时钟同步

timedatectl set-ntp true

Proxmox VE(PVE) 7.x下,LXC中安装Jellyfin

  1. 安装apt-transport-https,software-properties-common

    # Install HTTPS transport for APT as well as gnupg and lsb-release if you haven't already.
    apt-get install apt-transport-https software-properties-common -y
  2. 加入Universe仓库

    # Enable the Universe repository to obtain all the FFMpeg dependencies:
    add-apt-repository universe
  3. 获取密钥

    # Import the GPG signing key (signed by the Jellyfin Team):
    wget -O - https://repo.jellyfin.org/ubuntu/jellyfin_team.gpg.key | apt-key add -
  4. 添加Jellyfin源

    # Add a repository configuration at /etc/apt/sources.list.d/jellyfin.list:
    echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/ubuntu $( lsb_release -c -s ) main" | tee /etc/apt/sources.list.d/jellyfin.list
  5. 更新源

    apt-get update
  6. 安装Jellyfin

    apt-get install jellyfin -y
  7. 查看Jellyfin运行状态

    service jellyfin status
  8. 开机启动

    systemctl enable jellyfin
  9. 打开网站

    http://192.168.1.101:8096

Proxmox VE(PVE) 7.x下,LXC中开启Jellyfin硬解

经过测试,我们并不需要在宿主机安装驱动。本着不污染宿主机的精神,不对宿主机进行任何操作

  1. 安装 gpg-agent

    apt-get install -y gpg-agent
  2. 获取密钥

    wget -qO - https://repositories.intel.com/graphics/intel-graphics.key |  apt-key add -
  3. 新增安装源

    echo "deb [trusted=yes arch=amd64] https://repositories.intel.com/graphics/ubuntu focal main" > /etc/apt/sources.list.d/intel-graphics.list
  4. 更新源

    apt-get update
  5. 安装驱动

    apt-get install -y intel-media-va-driver-non-free intel-gpu-tools vainfo
  6. 测试驱动是否正常

    vainfo

    输出以下内容则正常

    测试驱动是否正常

  7. 在Jellyfin控制台中选中播放,并启用硬解,注意你的核显或显卡支持哪些格式,如果需要启动低功耗模式,需要在宿主机进行一些配置,这里我就不进行修改了

    开启Jellyfin硬解

解决Jellyfin中文显示框框的问题

因为Jellyfin对中文字体支持不好,所以我们可以通过Jellyfin管理页面的备用字体来解决这个问题。为了后续可以一次性配置完成,所以我选择先上传字体

  1. 启动Root账号登陆

    nano /etc/ssh/sshd_config
  2. 修改PermitRootLogin项为yes,如该项为被注释状态(最前面有个#),则先取消该项注释(删掉#号)

    修改PermitRootLogin项为yes

  3. 重启ssh

    systemctl restart sshd
  4. 复制字体,我选择的是微软雅黑,直接在Windows中复制的,如果你是想要公开使用你的视频网站,甚至是商用,请注意版权问题....

    在ubuntu中先新建一个存放字体的目录,Jellyfin的默认目录为: /usr/share/fonts/truetype/dejavu,所以我选择在相同目录下新建一个文件夹

    mkdir /usr/share/fonts/truetype/msyh

    在windows或者其他你所使用的操作系统

    scp -R ~/Desktop/msyh* root@192.168.1.101:/usr/share/fonts/truetype/msyh/

    在控制台中选择播放,启用备用字体,这里需要注意的是路径最后需要有一个斜杆,否则无法找到字体

    启用备用字体

  5. 修改完成之后需要重启

    systemctl restart jellyfin

    或者直接重启服务器

    reboot

Jellyfin挂载群晖或者其他NAS系统的Samba服务

1. 安装CIFS,并挂载Samba

  1. 安装CIFS

    apt-get install cifs-utils -y
  2. 创建被挂载的文件目录

    mkdir -p /mnt/nas/nasname/samba
  3. 挂载Samba(非永久,可自行在/etc/fstab中配置开机自动挂载,我使用的是另一种方式)

    mount -t cifs //你的NAS的IP/你的共享目录 /mnt/nas/nasname/samba -o user=你的账号,password=你的密码,vers=2.1,mfsymlinks

2. Proxmox VE(PVE) 7.x 安装虚拟交换机

如果你的NAS跟你的LXC容器均在同一台Proxmox主机下,你可以通过虚拟交换机来实现内部通讯,只要你的CPU性能够强,是完全可以跑满硬盘速度的。

  1. 安装openvswitch
apt-get install openvswitch-switch -y
  1. Network->Create->OVSBridge

    IPV4中写入: 10.0.0.1/8

    OVSBridge

  2. Network->Create->OVSIntPort

    name中写入: ovseno1, OVS Bridge中选中vmbr1

    OVSIntPort

  3. 分别在LXC容器与你的NAS虚拟机中新建网卡,均选中vmbr1,并输入你想要的IP地址,切记LXC的IP段与你的NAS的IP段相同,且都不输入网关

    新增虚拟网卡

3. (可选) 延迟挂载Samba,并自动识别NAS是否在线

相信很多朋友在使用Proxmox的同时,会将NAS系统安装在Proxmox之中,所以其他虚拟机想要挂载对应的Samba或者NFS服务,一般都是采用延迟启动的方式,这是一个方案。但考虑到有时候我会关闭NAS虚拟机,所以我更期望的方式是自动检测到对应的NAS系统启动后,自动挂载。于是我编写了以下脚本

  1. 创建脚本存放的目录

    mkdir /usr/script
  2. 编写脚本

    nano /usr/script/nasname-smb.sh

    写入以下代码,需要注意的是,我将离线日志写入到系统日志中,如果你有长时间不在线的情况下,请自行修改对应的脚本内容,以免出现过多的日志内容

    #!/bin/bash
    # author alain
    # site:https://www.alainlam.cn
    # 循环检测Samba服务器是否在线,并自动挂载
    
    server_ip="10.0.0.101"
    server_path="/media"
    mount_point="/mnt/nasname/media"
    # 是否循环检查是否在线(没有挂载时)
    online_check=true
    # 循环检查是否在线的间隔时间(没有挂载时)
    online_check_interval=10
    # 离线检查
    offline_check=true
    # 离线检查间隔时间
    offline_check_interval=60
    # SMB账号
    smb_username="你的账号"
    # SMB密码
    smb_pwd="你的密码"
    
    # 是否已经挂载
    isMounted=false
    
    while :; do
    
       if mountpoint -q $mount_point; then
           if ! $isMounted; then
               # 设置为挂载状态
               isMounted=true
               echo "SMB挂载成功"
               if $offline_check; then
                   echo "开启在线状态检测,间隔时间${offline_check_interval}s"
               fi
           fi
           if $offline_check; then
               sleep $offline_check_interval
               continue
           fi
       else
           # 设置为非挂载状态
           isMounted=false
           echo "SMB没有挂载,ping ${server_ip} ..."
           if (ping -c 1 -w 5 $server_ip >/dev/null 2>&1); then
               echo "${server_ip}在线,尝试挂载"
    
               # 判断挂载目录是否存在
               if [ ! -d $mount_point ]; then
                   echo "挂载目录不存在,新建目录"
                   mkdir -p $mount_point
               fi
    
               if [ ! -d $mount_point ]; then
                   echo "挂载目录不存在,取消挂载,请检查权限, code:403"
                   exit 403
               fi
    
               # 挂载SMB网络硬盘
               mount.cifs -o vers=2.1,username=$smb_username,password=$smb_pwd //$server_ip$server_path $mount_point
    
               if mountpoint -q $mount_point; then
                   continue
               else
                   echo "挂载失败"
                   if $online_check; then
                       echo "继续尝试挂载${server_ip},间隔时间${online_check_interval}s"
                       sleep $online_check_interval
                       continue
                   else
                       echo "不继续尝试挂载,退出脚本,code:404"
                       exit 404
                   fi
               fi
           else
               if $online_check; then
                   echo "${server_ip}离线,上线检查间隔时间${online_check_interval}s"
                   sleep $online_check_interval
                   continue
               else
                   echo "不循环检查,退出脚本,code:404"
                   exit 404
               fi
           fi
       fi
    
    done
  3. 加入执行权限

    chmod +x /usr/script/nasname-smb.sh
  4. 编写开机启动服务

    nano /etc/systemd/system/nasname-smb.service

    写入以下代码

    [Unit]
    Description=Automatically mount the SMB folder from nasname
    After=network.target
    
    [Service]
    Type=simple
    ExecStart=/usr/script/nasname-smb.sh
    
    [Install]
    WantedBy=multi-user.target
  5. 设置开机启动

    systemctl enable --now nasname-smb.service
  6. 查看运行效果

    延迟挂载Samba

Jellyfin开启Https

当你希望使用Nginx进行反向代理时,你可以跳过此步骤,直接看Nginx反向代理部分

  1. 新建存放SSL证书的目录

    mkdir -p /etc/ssl/certificates
  2. 上传证书到指定目录

    scp -R ~/Desktop/alainlam.cn* root@192.168.1.101:/etc/ssl/certificates/
  3. 进入证书目录,并生成pfx证书

    进入证书目录

    cd /etc/ssl/certificates/

    生成pfx证书

    openssl pkcs12 -export -out alainlam.cn.pfx -inkey alainlam.cn.key -in alainlam.cn.pem

    根据提示输入密码,可设置为空

  4. 修改证书所有者

    chown jellyfin:jellyfin /etc/ssl/certificates/ -R
  5. 在Jellyfin控制台中启用Https

    在Jellyfin控制台中启用Https

  6. 填写证书路径

    证书路径

    其中强制HTTPS为可选

  7. 完成配置后需要重启Jellfyfin

最后效果展示

Jellyfin效果图

扩展阅读

Jellyfin使用80/443端口,Nginx反向代理或UFW端口转发

标签: Jellyfin NAS Proxmox VE
最后更新:2022年12月29日

Alain

看了我的文,就是我的人,点个赞再走成不成

点赞
< 上一篇
下一篇 >

文章评论

  • TriATK

    文章不错, 但是不知道你有没有实际长时间运行你的服务.
    首先exit 404完全没必要, 只会导致服务结束, 而最重要的断线重连就无从提起了.
    而且LXC容器运行一段时间后会断连, 而实际上smb服务器(我直接用的win server 2022)并没有离线.
    此时你的systemd服务mount会报错
    mount error(11): Resource temporarily unavailable
    解决方法只有umount -a -t cifs再mount -a -t cifs
    有时甚至umount都无响应, 只能重启容器.

    最后我发现最简单实现断线重连的办法就是在pve->datacenter->storage里添加cifs存储(Content随便选一个就行).
    添加完后会被挂载到/mnt/pve/底下
    然后修改你的LXC配置文件
    nano /etc/pve/lxc/107.conf
    在最后面加上
    lxc.mount.entry: /mnt/pve/f-serv01/NAS/media media none bind 0 0
    lxc.mount.entry: /mnt/pve/f-serv01/NAS/downloads downloads none bind 0 0
    重启容器.
    这样你就拥有了自动挂载自动断线重连的bind mount了, 稳定度比LXC容器内的挂载脚本或者systemd服务高得多.

    PS:
    创建LXC容器可以试试现成的一键脚本:
    https://tteck.github.io/Proxmox/
    显卡直接直通的, 只需要自己加上网桥和挂载就能用了.

    2023年1月21日
    回复
    • Alain

      @TriATK 很高兴您的阅读,但是你可能没仔细看
      1. exit 404就是不再继续挂载了,输出日志就是怎么写的"不继续尝试挂载,退出脚本,code:404",前面我写了参数配置的,online_check
      2. LXC容器运行一段时间后失联...我真没遇到过,我一直在用这个脚本。
      3. pve->datacenter->storage这个方法我也写了,不过不在这篇文章,https://www.alainlam.cn/?p=278#toc-3,主要还是因为我是分开账号密码登录我的NAS的,HOST有自己的账号密码,其他部分容器也是,方便我自己管理
      4. 感谢你的分享

      2023年1月21日
      回复
      • TriATK

        @Alain 新年快乐! 谢谢您的回复, 我这可能是因为pve(v7.3-4) 用了6.1的内核问题还是啥的, LXC用脚本挂载稳定几个小时后就掉线而且大概率无法恢复, 只能重启容器.
        这个问题只出现在LXC容器而不会出现在VM里.
        出现问题的时候, dmesg会出现
        CIFS: VFS: cifs_mount failed w/return code = -11
        的错误.
        此时你容器内ping NAS是可以ping通的, 但是就是LXC容器的smb挂了, 其它vm里甚至docker里挂载的smb一点问题也没有, LXC和NAS本身的网络也是正常的.
        你的脚本, 在这种情况下会在执行到exit 403的时候自动跳出循环然后停止.
        虽然你本意是通过! -d $mount_point检测挂载点是否存在, 但是在出错的时候.
        ! -d $mount_point 返回的也是true, 虽然挂载点实际上存在, 只是temporarily unavailable.
        此时跳出就不会再尝试挂载目录了, 也就没有达到断线重连的目的.

        其实pve->datacenter->storage的办法也能用不同账号密码, 只是会先挂载在HOST里面罢了. 而且你用
        lxc.mount.entry的这种写法的话. Snapshot和增量backup亲测都没有问题, 我是用的独立的proxmox backup server(v2.3-2).

        我之前jellyfin一直是用的docker, 最近为了试试12代iGPU硬解才移到LXC容器的, 没想到就碰到这个频繁掉线的问题.

        2023年1月21日
        回复
        • Alain

          @TriATK 我用的是也是7.3-4,但是我没有升级内核。
          所以结论是在6.1内核上,检查挂载正常代码正常,因为离线所以返回为false,而判断文件夹是否还在的代码也正常,因为目录已经不在了,所以非条件下返回为true,好像逻辑上没什么问题。
          关键点是在上一个判断创建目录的地方mkdir -p $mount_point,并无法创建成功,所以判定为无权限操作,退出程序。所以这里可以优化一下代码,把文件夹创建放到最前面,后续在在线检测不再创建文件夹,只是尝试断开重新挂载。

          嗯,确实是可以。考虑到安全问题,所以我NAS上的文件夹也是不同权限访问的,所以我本来也有不想把账号都扔在一起的目的。

          2023年1月21日
          回复
    • Alain

      @TriATK 另外,祝你新年快乐,早点休息!

      2023年1月21日
      回复
    • Owen

      @TriATK 使用这个配置后,权限怎么配置呢?挂载后是root权限,jellyfin要使用的话还得都改一下权限吗?
      lxc.mount.entry: /mnt/pve/f-serv01/NAS/media media none bind 0 0
      lxc.mount.entry: /mnt/pve/f-serv01/NAS/downloads downloads none bind 0 0

      2024年2月26日
      回复
      • Alain

        @Owen 邮箱回复你了,这里备注下
        ----------------------------
        看起来你似乎是想挂载主机的目录,如果你是特权容器的话(Jellfyin根据一系列操作也可以做到非特权),那么你容器的root是可以修改权限的,将目录权限分配给Jellfin即可。但是这样修改后,host主机的权限有可能会跟容器内对应不上,所以更推荐的做法就是容器内用户映射到host主机的用户。
        假设你容器外目录权限给了1005,那么在你的lxc.conf中加入

        # uid map: from uid 0 map 1005 uids (in the ct) to the range starting 100000 (on the host), so 0..1004 (ct) → 100000..101004 (host)
        lxc.idmap = u 0 100000 1005
        lxc.idmap = g 0 100000 1005
        # we map 1 uid starting from uid 1005 onto 1005, so 1005 → 1005
        lxc.idmap = u 1005 1005 1
        lxc.idmap = g 1005 1005 1
        # we map the rest of 65535 from 1006 upto 101006, so 1006..65535 → 101006..165535
        lxc.idmap = u 1006 101006 64530
        lxc.idmap = g 1006 101006 64530

        /etc/subuid中加入
        root:1005:1
        /etc/subgid中加入
        root:1005:1

        你也可以将这两个id分配给指定用户
        sudo useradd -u 1005 -g 1005 -s /usr/sbin/nologin username

        2024年2月28日
        回复
    • Charles

      @TriATK '创建LXC容器可以试试现成的一键脚本:
      https://tteck.github.io/Proxmox/
      显卡直接直通的, 只需要自己加上网桥和挂载就能用了.'

      我仔細研究了一下大神的腳本,他裡面的 CT 創建裡面,真的有針對 Jellyfin, Plex, Frigate 等等的直通設定,確實牛:

      if [[ "$APP" == "Channels" || "$APP" == "Emby" || "$APP" == "Frigate" || "$APP" == "Jellyfin" || "$APP" == "Plex" || "$APP" == "Scrypted" || "$APP" == "Tdarr" || "$APP" == "Unmanic" ]]; then
      cat <<EOF >>$LXC_CONFIG
      # VAAPI hardware transcoding
      lxc.cgroup2.devices.allow: c 226:0 rwm
      lxc.cgroup2.devices.allow: c 226:128 rwm
      lxc.cgroup2.devices.allow: c 29:0 rwm
      lxc.mount.entry: /dev/fb0 dev/fb0 none bind,optional,create=file
      lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir
      lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file
      EOF
      fi

      2024年9月8日
      回复
  • eurstein

    谢谢,帮我解决了pve+lxc显卡直通问题

    2023年6月23日
    回复
  • 取消回复

    文章目录
    • 前因
    • 使用LXC安装Ubuntu 22.04系统
    • Proxmox VE(PVE) 7.x 下,LXC"直通"核显
    • (可选) Proxmox VE(PVE) 7.x下, LXC"直通"网卡
    • 解决LXC容器内Ubuntu Server 22.04显示中文乱码问题
    • 修改Linux的时区
    • Proxmox VE(PVE) 7.x下,LXC中安装Jellyfin
    • Proxmox VE(PVE) 7.x下,LXC中开启Jellyfin硬解
    • 解决Jellyfin中文显示框框的问题
    • Jellyfin挂载群晖或者其他NAS系统的Samba服务
      • 1. 安装CIFS,并挂载Samba
      • 2. Proxmox VE(PVE) 7.x 安装虚拟交换机
      • 3. (可选) 延迟挂载Samba,并自动识别NAS是否在线
    • Jellyfin开启Https
    • 最后效果展示
    • 扩展阅读

    COPYRIGHT © 2022 Alain's Blog. ALL RIGHTS RESERVED.

    Theme Kratos Made By Seaton Jiang