Skip to content
BinaryPatrick
Go back

Plex Hardware Transcoding in an LXC (QuickSync)

Edit page

A giant transcoding robot eager to be set free

For a long time I’ve been trying to configure my Intel 12500 iGPU to transcode, and for a long time I’ve been failing. I literally mean years trying to get this to work. Taking stabs at it every so often, thinking I’ve gotten it, or gotten close only to fail. Now that I’ve actually got it working, I want to share, and hopefully help whoever else is struggling with this.

In my hunt, I’ve dug through proxmox guides in the forums, blog posts, youtube guides. I basically had given up, until I figured out the piece that was missing.

Understand your Hardware

Every device is different, and the numbers matter. So I start by first enumerating my devices.

ls -la /dev/dri

The DRI in /dev/dri stands for Direct Rendering Infrastructure. It’s a directory in Linux that contains device files used for direct GPU access.

Typically you’ll find /dev/dri/card0, card1, etc. These respresent the GPU(s) installed in the machine.

Alongside them are the render nodes. /dev/dri/renderD128, renderD129 These are also important for transcoding. They allow unprivileged GPU access for compute and rendering tasks (3D rendering, video encoding/decoding, GPU-accelerated computing) without requiring display out. Applications like Vulkan, OpenGL, VA-API, and CUDA can use these.

drwxr-xr-x  3 root root        100 Mar 16 15:04 .
drwxr-xr-x 21 root root       5260 Mar 18 20:12 ..
drwxr-xr-x  2 root root         80 Mar 16 15:05 by-path
crw-rw----  1 root video  226,   1 Mar 16 15:05 card1
crw-rw----  1 root render 226, 128 Mar 16 15:04 renderD128

You’ll note on my machine, there is no card0, but there is a card1 even though I only have 1 GPU. Also note the numbers following both the card and render node, 226:1 and 226:128. These are the device driver major and minor numbers, identify what driver to use.

NOTE

In proxmox, usually the user running PVE is root, so there shouldn’t be a permissions issue.

Granting access to the LXC

Stop your LXC in the GUI and then edit the configuration from the CLI. For this example I’m going to use LXC ID 100.

cd /etc/pve/lxc
nano 100.conf

In the configuration, you’ll see all of the resources used by the LXC. At the bottom you can see the 4 lines I’ve added:

arch: amd64
cores: 6

features: nesting=1
hostname: plex
memory: 4096
net0: name=eth0,bridge=vmbr0,firewall=1,gw=10.8.8.1,hwaddr=0E:1B:49:3D:1B:34,ip=10.8.8.100/24,tag=8,type=veth
onboot: 1
ostype: debian
rootfs: pool:vm-100-disk-1,size=32G
startup: order=3
swap: 1024
tags: debian13

# kernel permissions
+lxc.cgroup2.devices.allow: c 226:1 rwm
+lxc.cgroup2.devices.allow: c 226:128 rwm

# device mapping
+dev0: /dev/dri/card1,gid=44
+dev1: /dev/dri/renderD128,gid=105

cgroup v2

By default, LXC containers are denied access to all host devices. The cgroup device controller acts as a whitelist. Each lxc.cgroup2.devices.allow line punches a hole in that deny-all policy for a specific device.

Notice in the kernel permissions I’ve added the major and minor driver identifiers from before. 226:1 and 226:128 respectively.

Breaking it down by token:

So the full line is telling the cgroup to allow the LXC container to read, write, and create the character device with major:minor 226:128, which is my renderD128 render node.

Device Permissions

Next, under cgroup, I’ve added the paths to the hardware on the host. You’ll notice they match from before: /dev/dri/card1 and /dev/dri/renderD128.

Breaking it down by token:

One important thing to understand is the GID here is applied to the device node as seen from inside the container. That’s why it needs to match the GID of the video/render group inside the LXC specifically, not necessarily the host’s GID. Often they are the same, though sometimes they are not, which was my problem.

Once all that is configured and saved. I can start the LXC and run the following command inside the container to find the correct GID.

getent group video render

For my container, I got back the following.

video:x:44:plex
render:x:105:plex

This is where the GIDs in my configuration are derived, 44 and 105 respectively. If they don’t match, shut down the container and go back to the host lxc configuration and update them.

IMPORTANT

the device GID refers to the device node as seen from inside the container.

Restart or Reinstall Plex

Sometimes restarting Plex is all you need to get it to see the new device. In my case I actually had to reinstall it.

sudo systemctl restart plexmediaserver

or

sudo apt reinstall plexmediaserver
sudo systemctl enable --now plexmediaserver

On a reinstall, you should see your hardware device in the CLI output.

PlexMediaServer install: PlexMediaServer-1.43.0.10492-121068a07 - Installation starting.
PlexMediaServer install:
PlexMediaServer install: Now installing based on:
PlexMediaServer install:   Installation Type:   Update
PlexMediaServer install:   Process Control:     systemd
PlexMediaServer install:   Plex User:           plex
PlexMediaServer install:   Plex Group:          plex
PlexMediaServer install:   Video Group:         render
PlexMediaServer install:   Metadata Dir:        /var/lib/plexmediaserver/Library/Application Support
PlexMediaServer install:   Temp Directory:      /mnt/transcode  (set in Preferences.xml)
PlexMediaServer install:   Lang Encoding:       en_US.UTF-8
PlexMediaServer install:   Processor:           12th Gen Intel(R) Core(TM) i5-12500T
PlexMediaServer install:   Intel i915 Hardware: Found
PlexMediaServer install:   Nvidia GPU card:     Not Found
PlexMediaServer install:
PlexMediaServer install: Completing final configuration.
PlexMediaServer install: Starting Plex Media Server.
PlexMediaServer install: PlexMediaServer-1.43.0.10492-121068a07 - Installation successful.  Errors: 0, Warnings: 0

Then check to make sure the service is running.

sudo systemctl status plexmediaserver
* plexmediaserver.service - Plex Media Server
     Loaded: loaded (/lib/systemd/system/plexmediaserver.service; enabled; preset: enabled)
     Active: active (running) since Thu 2026-03-19 02:03:02 UTC; 2min 22s ago
   Main PID: 3412 (Plex Media Serv)
      Tasks: 71 (limit: 18742)
     Memory: 96.7M
        CPU: 2.984s

Configuring Transcoding

In Plex, go to settings and then on the sidebar Settings > Transcoder. Make sure to check Use hardware-accelerated video encoding, and the device should now appear in the Hardware transcoding device dropdown. For me it’s an Intel Alder Lake-S GT1 [UHD Graphics 770], and most importantly supports Intel QuickSync.

Transcoding setting in plex

Now when I play a video, I see the venerated (hw) tag

Transcoded stream in the plex dashboard

Just to be sure, you can also run intels GPU top which shows the render and video usage.

sudo intel-gpu-top

🎉🎉🎉 Happy Transcoding 🎉🎉🎉


Additional Reading

Here are some blog posts and resources that I found helpful too


Edit page
Share this post on:

Next Post
Passing SMB to LXC on Proxmox