GPU passthrough to Docker container inside Proxmox LXC

Here's how I setup iGPU passthrough for Docker containers inside privileged Proxmox LXC's to achieve hardware accelerated video transcoding. I'm using integrated graphics on an Intel CPU, so I will be using i915 drivers.

Configuration

Start by loading the device drivers in Proxmox host shell and making them persistent.

modprobe i915
echo "i915" > /etc/modules-load.d/i915.conf

Check that render device (card or renderD128) is found.

$ ls -l /dev/dri
total 0
drwxr-xr-x 2 root root         80 Feb 12 20:42 by-path
crw-rw---- 1 root video  226,   1 Feb 12 20:44 card1
crw-rw---- 1 root render 226, 128 Feb 12 20:42 renderD128

Pass the device to LXC by editing the container config.

nano /etc/pve/lxc/<CTID>.conf

# Inside config add mount entry and allow access to the device
lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir 
lxc.cgroup2.devices.allow: c 226:* rwm

Restart the LXC.

pct reboot <CTID>

Inside LXC shell check that the device exists and is found.

ls -l /dev/dri

Install vainfo and drivers to the LXC.

apt-get update
apt-get install vainfo i915-va-drivers

Test that VAAPI works with the device by running vainfo.

vainfo

Vainfo should print out supported video profiles and entrypoints without display errors.

$ vainfo
Trying display: wayland
Trying display: x11
error: can't connect to X server!
Trying display: drm
libva info: VA-API version 1.22.0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so
libva info: Found init function __vaDriverInit_1_22
libva info: va_openDriver() returns 0
vainfo: VA-API version: 1.22 (libva 2.22.0)
vainfo: Driver version: Intel iHD driver for Intel(R) Gen Graphics - 25.2.3 ()
vainfo: Supported profile and entrypoints
      VAProfileMPEG2Simple            : VAEntrypointVLD
      VAProfileMPEG2Main              : VAEntrypointVLD
      VAProfileH264Main               : VAEntrypointVLD
      VAProfileH264Main               : VAEntrypointEncSliceLP
      VAProfileH264High               : VAEntrypointVLD
      VAProfileH264High               : VAEntrypointEncSliceLP
      VAProfileJPEGBaseline           : VAEntrypointVLD
      VAProfileJPEGBaseline           : VAEntrypointEncPicture
      VAProfileH264ConstrainedBaseline: VAEntrypointVLD
      VAProfileH264ConstrainedBaseline: VAEntrypointEncSliceLP
      VAProfileVP8Version0_3          : VAEntrypointVLD
      VAProfileHEVCMain               : VAEntrypointVLD
      VAProfileHEVCMain10             : VAEntrypointVLD
      VAProfileVP9Profile0            : VAEntrypointVLD
      VAProfileVP9Profile2            : VAEntrypointVLD

Next get the group ID of the group that owns renderD128 (usually render).

getent group render

Edit the docker container you want the device passed to.

nano docker-compose.yml

Add the device and group to the container.

devices:
  - /dev/dri:/dev/dri
group_add:
  - "" #RENDER GROUP ID HERE

Restart container.

docker compose restart

Check that the device mounted inside the docker container.

docker exec -it <container_name> bash
$ ls -l /dev/dri
total 0
crw-rw---- 1 root video 226,   1 Mar  1 05:05 card1
crw-rw---- 1 root   993 226, 128 Mar  1 05:05 renderD128

Now you should be able to configure hardware acceleration from your application settings.

Removing passthrough

To remove device passthrough go backwards removing all changes and installed packages.

  1. Remove changes from docker configs and restart container.

  2. Uninstall LXC packages.

    apt-get purge vainfo i915-va-drivers
  3. Remove changes from LXC configs and restart LXC.

  4. Unload drivers only if they are not in use by anything else.

    modprobe -r i9
    rm /etc/modules-load.d/i915.conf

Lassi Hirvonen, 5.3.2026