
Running inference or GPU compute inside an Incus instance, without dedicating a whole machine, is exactly what the gpu device allows. For a container, Incus shares the host GPU and injects the NVIDIA userspace by itself (nothing to install inside); for a virtual machine, it is an exclusive PCI passthrough. This guide covers both, including the driver version trap. Tested with an NVIDIA H100 on Incus 7.0.
What you will learn
- The difference between a container (sharing) and a VM (exclusive passthrough).
- Attach an NVIDIA GPU to a container with
nvidia.runtime. - Filter the right GPU on a multi-card machine.
- The driver version traps.
Prerequisites
- A host with an NVIDIA GPU and its kernel driver installed (
nvidia-smiworks on the host). - Incus installed: see installing Incus.
- For automatic injection into containers:
nvidia-container-toolkit(thelibnvidia-containerpackage) on the host.
Container or VM: two different mechanisms
This is the point to grasp first. The gpu device does not do the same thing depending on the instance type.
| Type | Mechanism | Sharing | Driver inside the instance |
|---|---|---|---|
| Container | Shares the host /dev/nvidia* devices | Yes, across instances | Injected by nvidia.runtime |
| Virtual machine | PCI passthrough (VFIO) | No, exclusive to the VM | Installed inside the VM |
For inference shared across several environments, the container is the more flexible route. For strong isolation or a different guest operating system, the virtual machine takes the GPU exclusively.
Passing a GPU to a container
The elegant part of Incus: with nvidia.runtime=true, it mounts the host NVIDIA userspace (libraries and nvidia-smi) into the container. No CUDA package to install inside.
-
Launch a container with the NVIDIA runtime enabled:
Fenêtre de terminal incus launch images:debian/13 gpu-lab -c nvidia.runtime=true -
Attach the GPU with a
gpudevice:Fenêtre de terminal incus config device add gpu-lab gpu0 gpu# Device gpu0 added to gpu-lab -
Check inside the container, with nothing installed in it:
Fenêtre de terminal incus exec gpu-lab -- nvidia-smi -LGPU 0: NVIDIA H100 PCIe (UUID: GPU-ada5ffa8-3c66-...)
The host GPU is seen as it is inside the container, with the /dev/nvidia0 and /dev/nvidiactl nodes exposed. Since this is sharing, several containers can receive the same GPU.
Targeting the right GPU
On a machine with several cards, the gpu device without a filter exposes all of them. You restrict it with filtering properties.
# by card identifierincus config device add gpu-lab gpu0 gpu id=0
# by PCI addressincus config device add gpu-lab gpu0 gpu pci=0000:81:00.0You can also filter by vendorid and productid. This is essential to dedicate one card to an instance and leave others free for the host or for other instances.
GPU in a virtual machine
For a virtual machine, the gpu device triggers a PCI passthrough: the card is detached from the host and attached to the VM, exclusively. The host can no longer use it while the VM runs.
incus launch images:debian/13 gpu-vm --vmincus config device add gpu-vm gpu0 gpuThe driver version trap
The most frequent problem in containers is a version mismatch between the host kernel driver and the injected userspace. Since nvidia.runtime mounts the host userspace, the two are aligned by construction here. If, however, you install NVIDIA packages by hand inside the container, they can conflict with the host kernel driver (Failed to initialize NVML: Driver/library version mismatch). The rule: in a container, let nvidia.runtime manage the userspace and install no driver inside.
Key points
- The
gpudevice means sharing in a container and an exclusive PCI passthrough in a virtual machine. - In a container,
nvidia.runtime=trueinjects the NVIDIA userspace: nothing to install inside. - Injection requires
libnvidia-container(nvidia-container-toolkit) on the host. - Target a specific card with
id=,pci=orvendoridandproductid. - In a virtual machine: the driver goes in the guest, and IOMMU is required on the host.
FAQ: common questions about GPU in Incus
nvidia.runtime plus a gpu device
incus launch images:debian/13 gpu-lab -c nvidia.runtime=true
incus config device add gpu-lab gpu0 gpu
incus exec gpu-lab -- nvidia-smi -L
With nvidia.runtime=true, Incus mounts the host NVIDIA userspace (libraries and nvidia-smi) into the container: nothing to install inside. The gpu device exposes /dev/nvidia0 and /dev/nvidiactl. Several containers can share the same card.
Sharing against exclusive passthrough
| Type | Mechanism | Sharing | Driver |
|---|---|---|---|
| Container | Shares /dev/nvidia* |
Yes | Injected by nvidia.runtime |
| Virtual machine | PCI passthrough (VFIO) | No, exclusive | Installed in the guest |
The container suits sharing between environments. The virtual machine takes the GPU exclusively and requires IOMMU enabled on the host (intel_iommu=on or amd_iommu=on).
Two frequent causes
libnvidia-containermissing on the host: thenvidia.runtimeinjection relies on that package (shipped bynvidia-container-toolkit, the same one Docker uses). Without it, nothing is mounted andnvidia-smifails.A driver installed by hand inside the container: it conflicts with the host kernel driver (
Failed to initialize NVML: Driver/library version mismatch).
The rule: in a container, let nvidia.runtime handle the userspace, and install nothing inside.
Filtering the gpu device
# by card identifier
incus config device add gpu-lab gpu0 gpu id=0
# by PCI address
incus config device add gpu-lab gpu0 gpu pci=0000:81:00.0
You can also filter by vendorid and productid. Without a filter, the gpu device exposes every card. Filtering is essential to dedicate one card to an instance and leave the others free.
Next steps
- Managing instances: the devices and configuration around the card you just attached.
- Incus OS without a shell: the immutable system where the NVIDIA driver version follows the atomic OS updates.
- Securing Incus: what exposing a host device to an instance implies.