Nvidia GPU passthrough in LXC

Status: CURRENT — MAJOR 2026 UPDATE
Last reviewed: 31 August 2026
Applies to: Proxmox VE 8.2+/9.x, NVIDIA GPU device sharing into LXC containers

The idea behind this article is still useful, but the old configuration method is not. Current Proxmox has native LXC Device Passthrough, so you no longer need to hand-write cgroup rules and bind mounts for every NVIDIA device.

Credit where it’s due: the original version of this guide was based on TheOrangeOne’s NVIDIA LXC GPU passthrough article. That method got me working at the time, but Proxmox has made this a hell of a lot cleaner since then.

First: this is not PCIe passthrough

With normal PCIe passthrough you hand the physical GPU over to one VM. The host effectively lets go of it.

This setup is different. The NVIDIA driver stays loaded on the Proxmox host, and the host’s NVIDIA device nodes are exposed to an LXC.

That means the same physical NVIDIA GPU can potentially be exposed to multiple containers at the same time.

Think of it as sharing access to the host GPU driver, not giving the entire PCIe device away.

The old guide is very old now 🙂

The original article used a GTX 760 with NVIDIA driver 450.80.02, manually downloaded the NVIDIA .run installer, created device nodes with custom udev rules, then edited the LXC config with lxc.cgroup2.devices.allow and lxc.mount.entry.

All of that made sense at the time. Most of it is now either unnecessary or something I’d avoid on a fresh build.

Jellyfin users: Jellyfin 10.11 currently requires NVIDIA driver 520.56.06 or newer. NVIDIA’s Kepler GPUs are limited to the 470 legacy driver branch, so the old GTX 760 example from this article no longer meets Jellyfin’s current driver requirement. The poor little thing has finally earned retirement 😅.

1. Install a working NVIDIA driver on the Proxmox host

The host still needs the real NVIDIA kernel driver. That part has not changed.

Before installing the driver, make sure DKMS and the headers for the running Proxmox kernel are available:

apt update
apt install dkms proxmox-headers-$(uname -r)


Then install a current NVIDIA driver that supports your GPU and kernel using the current Debian/NVIDIA package instructions.

I no longer recommend hard-coding an ancient direct download such as:

NVIDIA-Linux-x86_64-450.80.02.run


Package-managed drivers with DKMS are much easier to keep working across Proxmox kernel updates. If you deliberately use NVIDIA’s .run installer, make sure DKMS is enabled so the module can rebuild for new kernels.

Reboot if required, then verify the host first:

uname -r
nvidia-smi
dkms status


If nvidia-smi is cactus on the Proxmox host, stop here. The LXC isn’t going to magically fix it.

2. Check which NVIDIA device nodes exist

On the Proxmox host:

ls -l /dev/nvidia* /dev/nvidia-caps/* 2>/dev/null


A typical modern NVIDIA setup may contain some or all of:

  • /dev/nvidia0
  • /dev/nvidiactl
  • /dev/nvidia-uvm
  • /dev/nvidia-uvm-tools
  • /dev/nvidia-modeset
  • /dev/nvidia-caps/nvidia-cap1
  • /dev/nvidia-caps/nvidia-cap2

Don’t copy a list from a random guide and assume your machine has exactly the same devices. NVIDIA driver versions, GPU generations and workloads can differ.

The old guide also assumed fixed character-device major numbers such as 195 and 243. We don’t need to care about that anymore. Yewww.

3. Pass the NVIDIA devices into the LXC

Proxmox VE introduced native container device passthrough in 8.1, and from 8.2 you can configure it directly in the web interface.

Stop the LXC, then go to:

LXC → Resources → Add → Device Passthrough


Add the NVIDIA device nodes that exist on your host.

For a simple media-server setup I normally start with the common device set below. Replace 103 with your container ID and skip any device that doesn’t exist on your host:

pct set 103 --dev0 path=/dev/nvidia0,mode=0666
pct set 103 --dev1 path=/dev/nvidiactl,mode=0666
pct set 103 --dev2 path=/dev/nvidia-uvm,mode=0666
pct set 103 --dev3 path=/dev/nvidia-uvm-tools,mode=0666
pct set 103 --dev4 path=/dev/nvidia-modeset,mode=0666


If your workload needs the NVIDIA capability devices and they exist on your host, add them too:

pct set 103 --dev5 path=/dev/nvidia-caps/nvidia-cap1,mode=0666
pct set 103 --dev6 path=/dev/nvidia-caps/nvidia-cap2,mode=0666


About mode=0666: I’m using it here because it is the least painful way to prove the GPU works inside an unprivileged LXC. Proxmox creates the device node for the container with that access mode; you are not running a blanket chmod 666 /dev/nvidia* across the host.

Once everything works, you can tighten this using the uid, gid and mode options supported by Proxmox Device Passthrough.

Check what Proxmox saved:

pct config 103 | grep '^dev'


You should see entries similar to:

dev0: /dev/nvidia0,mode=0666
dev1: /dev/nvidiactl,mode=0666
dev2: /dev/nvidia-uvm,mode=0666
dev3: /dev/nvidia-uvm-tools,mode=0666
dev4: /dev/nvidia-modeset,mode=0666


4. Start the LXC and check the devices

Start the container and enter it:

pct start 103
pct enter 103


Then check the device nodes from inside the LXC:

ls -l /dev/nvidia* /dev/nvidia-caps/* 2>/dev/null


If they are present, the Proxmox side of the passthrough is basically done.

5. Install NVIDIA userspace libraries inside the LXC

This is the NVIDIA-specific annoying bit that still exists.

The LXC uses the host’s NVIDIA kernel module. You do not build another NVIDIA kernel module inside the container.

However, applications inside the LXC still need NVIDIA userspace libraries such as NVML, NVDEC and NVENC.

The userspace NVIDIA components inside the LXC need to be compatible with the NVIDIA kernel driver on the host. NVIDIA itself documents driver/library version mismatch errors when the client libraries and loaded kernel module don’t match.

For a Debian-based Jellyfin LXC, Jellyfin’s current documentation calls for its FFmpeg package plus the NVIDIA decode/encode libraries:

apt update
apt install jellyfin-ffmpeg7 libnvcuvid1 libnvidia-encode1


You will also need the matching NVIDIA userspace/NVML utilities for your driver branch so that nvidia-smi is available inside the LXC. Exact package names and versions vary depending on whether you’re using Debian’s NVIDIA packages or NVIDIA’s own repository, so keep them aligned with the host driver branch.

If you deliberately still use NVIDIA’s .run installer, installing the exact same driver version inside the LXC without kernel modules remains possible:

sudo sh ./NVIDIA-Linux-x86_64-<VERSION>.run --no-kernel-modules


I consider that the fallback method now, not the first choice. Package management + DKMS on the host is far less likely to turn a routine Proxmox update into a Saturday-night troubleshooting adventure.

6. Test NVIDIA from inside the LXC

nvidia-smi


If that shows the GPU, driver information and no NVML error, you’re in business.

If you get:

Failed to initialize NVML: Driver/library version mismatch


compare the loaded host driver and the libraries installed inside the LXC. That’s usually version drift, not a Proxmox device-passthrough problem.

7. Actually test hardware acceleration

nvidia-smi proving the GPU exists is nice, but it doesn’t prove Jellyfin/Plex can actually use NVENC/NVDEC.

Start a forced transcode and watch the GPU:

watch -n 1 nvidia-smi


You should see the transcoder process appear and GPU/video-engine activity increase.

For Jellyfin, select NVIDIA NVENC in the transcoding settings and only enable codecs your GPU actually supports. Current Jellyfin documentation is the best source for the codec/support matrix because NVIDIA’s generations and encode-session limits keep changing.

Can I share the same GPU with multiple LXCs?

Yes — and this remains one of the nicest reasons to do LXC device sharing instead of PCIe passthrough.

Because the NVIDIA driver remains owned by the Proxmox host, you can expose the same /dev/nvidia* device nodes to more than one LXC.

Obviously they still share the same physical GPU resources, VRAM and hardware encoder limits. We haven’t invented free GPUs yet. Bloody disappointing.

What if my app runs in Docker inside the LXC?

Then you’ve added another layer to the onion 🙂

This guide gets the NVIDIA GPU from Proxmox → LXC. If Jellyfin/Plex is then running inside Docker within that LXC, Docker also needs access to the NVIDIA devices/userspace stack. NVIDIA Container Toolkit or explicit Docker device mappings may be required depending on the image and runtime.

Always get nvidia-smi working directly inside the LXC first. Only then troubleshoot Docker. Otherwise you’re trying to debug two layers at once and life is too short.

Old method — archived

ARCHIVED — PRE-PROXMOX 8.1 METHOD

The old guide manually allowed NVIDIA character-device major numbers through cgroups and bind-mounted each device into the container. This is preserved only so old search results and existing installations make sense.

The old container configuration looked roughly like this:

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

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-modeset dev/nvidia-modeset none bind,optional,create=file
lxc.mount.entry: /dev/nvidia-uvm-tools dev/nvidia-uvm-tools none bind,optional,create=file


Current Proxmox Device Passthrough replaces both the manual cgroup permission rules and the bind mounts, including for unprivileged containers.

Old udev chmod hack — also archived

The original article also created a custom udev rule that ran nvidia-smi/nvidia-modprobe and then did a wildcard chmod 666 /dev/nvidia* on the host.

I wouldn’t do that by default now. Modern NVIDIA installations include nvidia-modprobe, whose job includes creating the /dev/nvidia* nodes when required, and Proxmox’s device passthrough can set the permissions of the container-side device node itself.

If the NVIDIA device nodes are missing on the host, diagnose the NVIDIA driver/module first rather than immediately masking it with a global permissions rule.

Quick troubleshooting order

  1. nvidia-smi works on the Proxmox host.
  2. The expected /dev/nvidia* nodes exist on the host.
  3. Those nodes are configured with Proxmox Device Passthrough.
  4. The device nodes appear inside the LXC.
  5. The LXC has compatible NVIDIA userspace libraries.
  6. nvidia-smi works inside the LXC.
  7. Only then test Jellyfin/Plex hardware transcoding.

Do it in that order and you know exactly which layer went cactus.

References

Much less black magic than the original version. The NVIDIA driver can still throw the occasional tantrum after a kernel update, obviously — it wouldn’t be NVIDIA on Linux otherwise 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *