Ir al contenido

Cómo configurar Jellyfin en LXC (Debian) con iGPU Passthrough en Proxmox

Jordi Fàbregas
Autor
Jordi Fàbregas
Administrador de Sistemas y Redes. Entusiasta del software libre.
Tabla de contenido

Introducción
#

Soy usuario de Jellyfin ya desde hace un tiempo. Recientemente, me compré un disco de mayor capacidad y decidí volver a reimplementar Jellyfin. Decidí cambiar algunas configuraciones, como:

  • instalar desde los repositorios para Debian en vez de docker, facilitando así el mantenimiento con unattended-upgrades.

  • Usar un contenedor LXC en ves de una VM para aprovechar mejor los recursos de mi limitado equipo, aceptando un menor aislamiento.

  • Configurar el passthrought de la GPU para aprovechar las posibilidades modernas de transcoding del procesador Intel N150 (Alder Lake)

Software y Hardware emprados:
#

Esta documentación se ha implementado sobre Proxmox VE 9, con un LXC de debian 13, un volumen SMB montado mediante OpenMediaVault y usando los repositorios oficiales de Jellyfin para debian

Como hardware usé un minipc con procesador Intel N150 Alder Lake

Nota importante: Las mejoras significantes de transcodificación en el Intel N150 se implementan a partir del kernel 6.11, por lo que se deberá usar PVE 9 o instalar un kernel superior en PVE 8

Configuración y instalación de LXC con Jellyfin
#

Primero descargaremos una imágent CT de debian 13. Crearemos un contenedor Unprivileged y le instalaremos Jellyfin mediante el instalador oficial para debian/ubuntu. curl -s https://repo.jellyfin.org/install-debuntu.sh | bash

Posteriormente, podemos instalar y configurar unattended-upgrades para automatizar las actualizaciones.

Pasar el volúmen SMB al LXC
#

Montar el volúmen en el host PVE
#

Aquí me encontré con uno de los primeros problemas. Para poder mantener el contenedor en estado sin privilegios, necesitaremos montar el volúmen SMB en el host de Proxmox y después pasar el mismo al contenedor mediante la configuración del mismo.

Para ello comprobaremos que el host proxmox tiene acceso y las credenciales de SMB son correctas: smbclient -L //DIRECCION_IP_OMV -U usuario_jellyfin

En el caso de conectar sin problemas, añadiremos el volúmen SMB a /etc/fstab

//IP_DE_OMV/CARPETA_SMB /mnt/smb/library cifs username=usuario_jellyfin,password=TU_CONTRASEÑA,iocharset=utf8,uid=100000,gid=100000,_netdev,x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.mount-timeout=30 0 0

IMPORTANTE: Usamos uid=100000 porque es el ID que Proxmox asigna al usuario root dentro de un contenedor sin privilegios.Puede que tengas que ajustar el uid y el gid de los contenedores en proxmox.

A continuación lo montamos mount -a y comprobamos que esté montado correctamente: cd /mnt/library && ls

Y comprobamos que la biblioteca SMB está montada correctamente al host proxmox

Pasar el volúmen al contenedor LXC Jellyfin
#

Apagaremos el contenedor de Jellyfin

En el host, editaremos el archivo del contenedor LXC

nano /etc/pve/lxc/ID_CONTENEDOR.conf

Añadiremos al final una línea relativa al final del archivo, para montar la carpeta dentro del contenedor

mp0: /mnt/smb/library,mp=/mnt/library

Configurar bibliotecas en Jellyfin
#

Este apartado no vale la pena documentarlo. Entras al panel web de Jellyfin y configuras el servidor según tus preferencias. Recuerda de añadir la bibilioteca almacenada en /mnt/library

Hacer passthrought de la GPU y resolver dependéncias
#

Una vez ya tenemos Jellyfin y la biblioteca funcionando. Apagamos de nuevo el contenedor LXC. Volveremos a modificar su configuración en /etc/pve/lxc/ID_CONTENEDOR.conf

Y añadimos la siguiente configuración

lxc.cgroup2.devices.allow: c 226:0 rwm
lxc.cgroup2.devices.allow: c 226:128 rwm
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

Esta configuración ha sido probada con intel N150. En principio deberia de funcionar con cualquier Intel y AMD pero no con nvidia. No se ha probado con otras configuraciones de hardware, solo con Intel N150

También tendremos que dar permisos en el host de proxmox para que el contenedor LXC pueda usarlos:

chmod 666 /dev/dri/renderD128

Las reglas sobre /dev/ se pierden al reinciar el host, si todo funciona correctamente tendremos que hacerlas permanentes.

Probablemente no sean los mejores permisos, pero estamos en un entorno de laboratorio sin acceso externo ni nada expuesto

Ahora ya podemos volver a encender el contenedor LXC y instalamos las siguientes dependéncias necesarias para transcodificar. Si no tenemos el repositorio non-freedeberemos añadirlo antes a nuestras fuentes de software.

sudo apt install intel-media-va-driver-non-free vainfo intel-opencl-icd libpvl2

Luego podemos ejecutar la órden vainfo en el contenedor LXC para ver si está reconociendo las capacidades de transcodificación del host.

img

Si todo está funcionando bien, crearemos una regla udev para que los permisos de /dev/dri/renderD128 se apliquen automáticamente en cada inicio:

echo 'KERNEL=="renderD128", MODE="0666"' > /etc/udev/rules.d/99-gpu-passthrought.rules

Configurar transcodificación en Jellyfin
#

Si todo está bien hasta ahora, ya podemos configurar la transcodificación de jellyfin. Para esto nos dirigiremos a Menu - Panel de control - Reproducción - Conversión

Como tipo de aceleración seleccionaremos Intel Quicksync (QSV)

Activaremos todas las opciones de decodificación por hardware, la codificación de bajo consumo (necesario para intel N150), la codificación en formato HEVC y dejaremos deshabilitada la codificación en formato AV1 (con mi hardware daba errores).

Dejo una cópia de mi configuración actual entera por si es de utilidad:

img

Comprobar el funcionamiento:
#

En el host de proxmox instalaremos el paquete intel-gpu-tools y ejecutaremos el programa intel_gpu_top

Desde un navegador web accedemos a jellyfin y reproducimos un video cualquiera. Una vez el video se esté reproduciendo, vamos a la configuración del video (rueda de ajustes) - Calidad y seleccionamos una calidad inferior para forzar la transcodificación de video. Si todo está funcionando correctamente, deberiamos ver en la terminal del host que ejecutamos intel_gpu_top algo parecido a esto:

img

Una vez finalizada la prueba, reiniciaremos el nodo de Proxmox y comprobaremos que se estén aplicando correctamente el montaje automático de SMB tanto en el nodo de proxmox como en el LXC y comprobaremos de nuevo con intel_gpu_top

Problemas comunes:
#

  • SMB no se monta al reiniciar el host o el LXC: Comprobar que en el host esté bien el archivo /etc/fstab. Comprobar los usuarios y credenciales, montar automáticamente con mount -apara ver si es un problema de orden de arranque. Depurar. Si el problema en el LXC revisar /etc/pve/lxc/ID_CONTENEDOR.conf
  • El passthrought desaparece después de reiniciar el host: Comprobar que la regla udev se haya creado correctamente en /etc/udev/rules.d/99-gpu-passthrought.rules
  • La interfaz web funciona y/o el video se reproduce bien, pero al usar la transcodificación o reproducir se detiene y no funciona: Revisar los logs desde el Panel web de jellyfin - Panel de control - Registros suele dar información precisa de que problema está impidiendo la reproducción
  • El contenedor LXC no arranca automáticamente al reiniciar y da un error Error: startup for container 'ID' failed, pero si lo arranco manualmente funciona. El contenedor ha intentado arrancar antes de que SMB o el passthrought estuvieran listos o el archivo /etc/fstab no está editado correctamente. Asegurate de que los uid y gid sean correctos. Las opciones noautoy x-systemd.automount también pueden ayudar. Aplicar reglas en el orden y tiempo de espera en el que las máquinas arrancan también puede ser necesario.

Fuentes para consulta:

N150 iGPU Passthrough | Proxmox Support Forum

Tutorial: Unprivileged LXCs - Mount CIFS shares | Proxmox Support Forum

Unprivileged LXC containers - Proxmox VE

SMB Mount in Unprivileged LXC – UID/GID Confusion | Proxmox Support Forum