Jellyfin Installation on LXC

Installation of Jellyfin, an open source media library alternative to Plex. Includes instructions on allowing the container to access the Nvidia card for transcoding.

Base Installation

Create a new privileged container with the Ubuntu 22.04 template.

Run apt update && apt upgrade -y to update the repositories and install updates.

Manual installation instructions of Jellyfin can be found on the Official Jellyfin Docs

I just used their script: curl https://repo.jellyfin.org/install-debuntu.sh | sudo bash

After the script completes, Jellyfin should be accessible from http://<Jellyfin-ip>:8096

If it is not accessible try to enable and start Jellyfin automatically with systemd:

sudo systemctl enable jellyfin && sudo systemctl start jellyfin

Adding Media

Since I have a TrueNAS system that stores all my data, it would make sense to have Jellyfin access all my content remotely. I used Samba instead of NFS because I had not looked into NFS permissions when I first set this up.

Most of this is based on Ubuntu's documentation on mounting windows shares.

Install CIFS utils with sudo apt install cifs-utils

Create a mount point for the share with sudo mkdir /mnt/jellyfin

Without Password

If the share has guest access enabled, then just add the following to fstab with sudo nano /etc/fstab

//Peanut/Media/Jellyfin    /mnt/Jellyfin    cifs    guest,uid=1000,iocharset=utf8    0    0

Mount with mount /mnt/Jellyfin

With Password

If the share has User Authentication, create a credentials file with nano ~/.creds

Add the following to the file and change the permissions to the file with chmod 600 ~/.creds

username=$USERNAME
password=$PASSWORD

Add the following to fstab with sudo nano /etc/fstab

//Peanut/Media/Jellyfin    /mnt/Jellyfin    cifs    credentials=/.creds,iocharset=utf8    0    0

Mount with mount /mnt/Jellyfin

Proxmox LXC + Nvidia Transcoding

I wanted to have the ability to use the transcoder on my Quadro M2000 while keeping it as my servers display out. I had to give the container permission to use the video device on the hypervisor. Make sure that your saved media formats are supported by the Nvidia card you have or want to get by referencing this.

My installation of Proxmox is on a ZFS Raid1, therefore utilizing the systemd-boot instead of GRUB. More detailed instruction can be found on the Official Proxmox Docs.

Enabling IOMMU

Look through the BIOS of your machine and enable IOMMU.

Edit the bootloader kernel config file with nano /etc/kernel/cmdline

Append quiet, amd_iommu=on, and iommu=pt to the end of the line

The options in the config file are separated by spaces.

The current CPU in my machine is a Ryzen 7 2700x, Intel based chips will have a different setup, refer to the PVE docs.

Save and exit from the text editor and run proxmox-boot-tool refresh

Reboot and verify by running dmesg | grep - e DMAR -e IOMMU

It should say that IOMMU is enabled

[    0.583711] pci 0000:00:00.2: AMD-Vi: IOMMU performance counters supported
[    0.584425] pci 0000:00:00.2: AMD-Vi: Found IOMMU cap 0x40
[    0.584558] perf/amd_iommu: Detected AMD IOMMU #0 (2 banks, 4 counters/bank).

Add the following lines to /etc/modules

vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd

Install Drivers on Host

We first need to blacklist the nouveau kernel drivers by running:

echo -e "blacklist nouveau\noptions nouveau modeset=0" > /etc/modprobe.d/blacklist-nouveau.conf

Then run update-initramfs -u and reboot

Run apt install pve-headers-$(uname -r) to install the headers

Download the latest Nvidia Drivers for your card and platform

wget https://us.download.nvidia.com/XFree86/Linux-x86_64/525.116.04/NVIDIA-Linux-x86_64-525.116.04.run

install make and gcc with apt install make gcc

Make the download file an executable chmod +x NVIDIA-Linux-x86_64-510.47.03.run

Run the script with ./NVIDIA-Linux-x86_64-510.47.03.run

Answer "no" when it asks if you want to install 32bit compatibility drivers
Answer "no" when it asks if it should update X config

Append the following to /etc/modules-load.d/modules.conf:

nvidia
nvidia_uvm

Run update-initramfs -u -k all

Add the following lines to /etc/udev/rules.d/70-nvidia.rules:

KERNEL=="nvidia", RUN+="/bin/bash -c '/usr/bin/nvidia-smi -L && /bin/chmod 666 /dev/nvidia*'"
KERNEL=="nvidia_uvm", RUN+="/bin/bash -c '/usr/bin/nvidia-modprobe -c0 -u && /bin/chmod 0666 /dev/nvidia-uvm*'"

Verify the host installation by running: nvidia-smi

Container Installation

Add these lines to /etc/pve/lxc/<id>.conf

lxc.cgroup2.devices.allow: c 195:* rwm
lxc.cgroup2.devices.allow: c 509:* rwm

Use ls -l /dev/nvidia* to see the ids and match them in the cgroup2 lines

Pass through the device files by appending the following to /etc/pve/lxc/<id>.conf

lxc.mount.entry: /dev/nvidia0 dev/nvidia0 none bind,optional,create=file
lxc.mount.entry: /dev/nvidiactl dev/nvidiactl none bind,optional,create=file
lxc.mount.entry: /dev/nvidia-uvm dev/nvidia-uvm none bind,optional,create=file
lxc.mount.entry: /dev/nvidia-uvm-tools dev/nvidia-uvm-tools none bind,optional,create=file

Wget the same Nvidia driver earlier on the container

Run the script with this argument: ./NVIDIA-Linux-x86_64-510.47.03.run --no-kernel-module arg

Make sure that the driver on the container is exactly the same as the driver on the host.

Verify the container installation by running: nvidia-smi

Enable Hardware Acceleration on Jellyfin

Navigate to the Jellyfin Web UI

Under Administration -> Dashboard -> Playback:

Change the "Hardware acceleration" option to Nvidia NVENC

Refer to the Nvidia GPU Encode and Decode Matrix to find the support file format for your card.

Check all of the boxes under "Enable hardware decoding for" to match the Nvidia reference sheet.

Verify by playing media that requires transcoding on the Web UI.

Tweaks + Notes

Power States

When running nvidia-smi, I noticed that the GPU was idling in the maximum performance power state: P0. To address this issue, I had to run the nvidia-persistenced, command to have the GPU change power states when needed. The command won't survive a reboot so I had to make a service for it.

Create a new script in /etc/init.d with nano /etc/init.d/fixQuadroPower

Add the following to the file:

#!/bin/bash
nvidia-persistenced

Save and exit

Make the file executable with chmod +x /etc/init.d/fixQuadroPower

Add the following line to /etc/crontab

 @reboot    root    /bin/bash    /etc/init.d/fixQuadroPower > /dev/null 2>&1

Check the results with nvidia-smi, the power state should be in idle P8 and the power draw should be noticeably lower.