Share one NVIDIA GPU between Proxmox LXC containers
Running AI at home needs a GPU, and a GPU is expensive. In Proxmox you do not have to give it to a single virtual machine. With LXC containers one NVIDIA card can serve several apps at the same time.
This is how our homelab does it: one RTX 3090 shared by four containers, on Proxmox VE 9.2.2. The commands and numbers below come from our own setup, checked on 2026-11-01. Your driver, kernel and device numbers will differ, so read the steps as a map, not a script to paste.
LXC or VM passthrough?
With VM passthrough the whole GPU is handed to one virtual machine, and nothing else, not even the host, can use it. With an LXC container the GPU stays with the host's NVIDIA driver, and each container is given access to the same device files. That means several containers can use one card at once, which is why we chose it: one RTX 3090 serves Ollama, ComfyUI, Applio and TTS-WebUI.
The price is that containers share the host kernel and the driver version, and they see the whole GPU with no VRAM isolation. We cover the consequences at the end.
Step 1: install the driver on the host
Install the build tools and the kernel headers that match your running kernel, and block the open-source nouveau driver. On Proxmox 9 the headers package is called proxmox-headers-<kernel>.
Download the official .run installer for your card from NVIDIA and run it on the host with the options below. DKMS rebuilds the kernel module when Proxmox updates the kernel. Do not let apt autoremove dkms later.
We used the NVIDIA installer because Debian's packaged 550 driver did not build on our 7.0.2-6-pve kernel. Your kernel may be different, so try the packaged driver first if you prefer.
Check the result with nvidia-smi on the host. It should list your card and the driver version.
Host commands
apt install build-essential dkms proxmox-headers-$(uname -r)
printf 'blacklist nouveau\noptions nouveau modeset=0\n' > /etc/modprobe.d/blacklist-nouveau.conf
update-initramfs -u && reboot
# after the reboot, with the .run file downloaded from nvidia.com:
sh NVIDIA-Linux-x86_64-<version>.run --silent --dkms --no-x-check --no-nouveau-check --install-libglvnd
nvidia-smi
Step 2: load the modules and create the device nodes at boot
Add the NVIDIA modules to /etc/modules-load.d/nvidia.conf so they load at boot.
The nvidia-uvm device node, which CUDA needs, is not always created until something asks for it. After a host reboot our containers started with no /dev/nvidia-uvm and CUDA failed inside them.
The fix is a small oneshot service that runs before the containers start. It calls nvidia-modprobe to create the nodes and nvidia-smi to wake the card. We checked it across real host reboots.
Add the lines below to the container's file in /etc/pve/lxc/<id>.conf, using your own major numbers, then restart the container.
Our containers are privileged. We have not tested unprivileged containers with ID mapping, so we cannot say how they behave.
The bind mounts use the optional flag so the container still starts if a device node is missing, but CUDA will then fail inside it. That is the first thing to check if the GPU disappears.
Step 5: install the matching driver inside the container
The container needs the NVIDIA user-space libraries, and the version must match the host driver exactly. Run the same .run file inside the container, but without the kernel module.
Check with nvidia-smi inside the container. It should show the same card and the same driver version as the host.
For Docker inside the container, install the NVIDIA container toolkit. In our containers we also had to set no-cgroups = true in its config, because the container cannot manage device cgroups itself.
Inside the container
sh NVIDIA-Linux-x86_64-<version>.run --silent --no-kernel-module --no-nouveau-check --no-x-check --install-libglvnd --no-systemd
nvidia-smi
What it looks like in daily use
Setup: Proxmox VE 9.2.2, kernel 7.0.2-6-pve, one RTX 3090 with 24 GB of VRAM, driver 595.84. Four AI containers share the card.
Measured VRAM from our own tests: Ollama with gpt-oss:20b about 13.7 GB, ComfyUI with an SDXL image about 7 GB, TTS-WebUI with Kokoro about 1.2 GB.
Together that is about 22 of the 24 GB, which leaves no headroom for longer prompts, bigger models or video, so we run one heavy job at a time. Light ones such as Kokoro usually fit beside another job.
ComfyUI keeps its models in VRAM after a job. A one-minute timer on that container frees them after five idle minutes, so the other containers can use the card.
The host's 15 GB of RAM is shared too. After an uncapped video test froze the whole host, ComfyUI runs with a hard memory limit of 13 GB.
These are one machine and a few short tests, not a benchmark.
The reboot trap
The dynamic major numbers can change after a host reboot. If nvidia-uvm or nvidia-caps gets a new number, the old allow lines in the container config no longer match, and the device files inside the container show up as dead nodes of 0 bytes.
After every host reboot we compare grep nvidia /proc/devices with the lxc.cgroup2.devices.allow lines of each GPU container. If they differ, edit the config and reboot that container.
Honest caveats
Privileged containers are less isolated than unprivileged ones. A process that escapes a privileged container is root on the host, so use this only for containers you trust.
The driver must match everywhere. Upgrading means the host and every GPU container in the same maintenance window.
A kernel update needs DKMS to rebuild the module. Check dkms status before rebooting into a new kernel, and keep a way to reach the host without a working display.
There is no VRAM isolation between containers. One job that fills the card can make another fail with out-of-memory errors.
A GPU under load draws a lot of power, makes noise and gets hot, so keep an eye on its temperature.
Package names, flags and paths change between Proxmox, kernel and driver versions. If something does not match, follow the current Proxmox and NVIDIA documentation.