LXC containers give you lightweight, highly customized environments with almost no overhead. The downside has always been hardware passthrough. Want to use your GPU? Traditionally you’d need a full VM for that. But we can actually pass through the Intel iGPU to an LXC container on Proxmox and get hardware transcoding for Plex or Jellyfin, while keeping all the benefits of LXC.
Configure Proxmox
Start by updating:
apt update && apt dist-upgrade
Since LXC containers share the host kernel, we need GPU drivers loaded on the Proxmox host itself.
Install GPU Drivers
Intel
Intel iGPU drivers are usually already loaded by default. Check:
ls /dev/dri | grep renderD
If you see a device named renderD followed by a number, you’re set. Skip ahead.
AMD
apt update && apt install firmware-amd-graphics libgl1-mesa-dri libglx-mesa0 mesa-vulkan-drivers xserver-xorg-video-all
Reboot to load the new drivers.
Nvidia
Add the Debian backports repo to /etc/apt/sources.list:
# buster-backports
deb http://deb.debian.org/debian buster-backports main contrib non-free
Then install:
apt update && apt install -t buster-backports nvidia-driver firmware-misc-nonfree
Reboot. You might also want to apply this patch to remove Nvidia’s transcoding limits on consumer cards.
Create LXC Container
Follow my Docker on Proxmox guide to create the container. If you’re going with Plex directly (no Docker), just create a regular privileged container and skip the Docker setup.
A word of warning: I’ve only tested this with privileged containers. Unprivileged might work but I haven’t verified it.
Update the container once it’s running.
Passthrough Your GPU
First, identify which GPU device to pass through:
ls -l /dev/dri
Usually the CPU’s built-in GPU shows up as renderD128 and card0. Add-on PCI GPUs get higher numbers like renderD129.
For this guide we’re passing through the Intel QuickSync GPU (renderD128, card0).
Add these lines to your container config at /etc/pve/lxc/<VMID>.conf:
lxc.cgroup.devices.allow: c 226:* rwm
lxc.mount.entry: /dev/dri/<Your card> dev/dri/card0 none bind,optional,create=file
lxc.mount.entry: /dev/dri/<Your RenderD> dev/dri/renderD128 none bind,optional,create=file
Real example:
lxc.cgroup.devices.allow: c 226:* 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
Reboot the container and verify the devices are visible inside:
ls -l /dev/dri/
Install Plex Media Server
Grab the right package from the Plex downloads page.
Debian/Ubuntu
apt update && apt install curl gpg2
echo deb https://downloads.plex.tv/repo/deb public main | sudo tee /etc/apt/sources.list.d/plexmediaserver.list
curl https://downloads.plex.tv/plex-keys/PlexSign.key | sudo apt-key add -
apt install plexmediaserver
Arch Linux
Install plex-media-server from the AUR.
Fedora
Install the RPM from the Plex download page, then enable the repo by editing /etc/yum.repos.d/plex.repo:
[PlexRepo]
name=PlexRepo
baseurl=https://downloads.plex.tv/repo/rpm/$basearch/
enabled=1
gpgkey=https://downloads.plex.tv/plex-keys/PlexSign.key
gpgcheck=1
Jellyfin
Follow the Jellyfin install docs and use the Docker method.
Let me know if I missed anything.