Proxmox · CT 211 “mediatest” · 14 August 2026

3090 Passthrough Runbook

Getting a local model onto the RTX 3090 from a Claude Code session that runs inside an unprivileged LXC container. Every command here runs somewhere I cannot reach, so this is written for you to run, not for me.

Blocked · no driver, no device nodes, 13 GB free

Findings

What I could see from inside the container

Collected from CT 211 on 14 August 2026. The two NVIDIA cards appear because LXC shares the host's sysfs — that is visibility, not access.

CheckResultState
GPU on PCI bus01:00.0 GA102 [GeForce RTX 3090]Present
Second GPU07:00.0 TU104GL [Quadro RTX 4000]Present
Driver in containernvidia-smi: not found · /proc/driver/nvidia: absentMissing
Device nodes/dev/nvidia*: noneMissing
NVIDIA libs in linker cache0 entriesMissing
Virtualisationlxc · running as uid 1001, no sudoUnprivileged
Inference runtimeno ollama, llama.cpp or vLLM · docker presentMissing
Model server on LANports 11434 / 8000 / 1234 / 5000 closed on 192.168.40.1 and .12None
Disk free on /13 GB of 32 GBToo small
RAM16 GB total, ~6 GB availableTight
The one that decides everything

The container is unprivileged and I am uid 1001 with no sudo, so I cannot install a driver, create device nodes, or edit the container config — that file lives on the Proxmox host at /etc/pve/lxc/211.conf, which is not visible from in here. Everything below step 0 needs a root shell on the host.

Step 0

Pick the route before you install anything

There are two ways to give this session a GPU-backed model, and they differ enormously in effort.

Recommended · serve it, don't pass it

Install the driver and Ollama on the Proxmox host (or a VM that already has the 3090), bind it to 0.0.0.0:11434, and point this container at it over HTTP. No device passthrough, no driver-version matching, no container config edits, and the 13 GB disk here stops mattering because the weights live on the host. Steps 1, 2 and 6.

The other route · passthrough

Bind the device nodes into CT 211 so the GPU is local to this session. More fragile: the driver inside the container must be the exact same version as the host's, and it breaks every time the host driver updates. Worth it only if something in here needs CUDA directly rather than an API. Steps 1 through 6.

Procedure

The commands

Run as root on the Proxmox host unless a step says otherwise.

  1. Check what the host already has

    where: proxmox host, as root

    If nvidia-smi already works here, skip to step 3. Also confirm neither card is currently passed through to a VM — a GPU bound to vfio-pci for a VM cannot also serve the host.

    # is a driver already loaded?
    nvidia-smi
    
    # which driver owns each card — look for "Kernel driver in use"
    lspci -nnk -d 10de:
    
    # anything bound to vfio-pci is reserved for a VM
    lsmod | grep -E 'nvidia|vfio'
  2. Install the driver on the host

    where: proxmox host, as root

    Proxmox is Debian, but it uses its own kernel headers package. Take the driver version from NVIDIA's site and keep a note of it — the passthrough route needs the identical version inside the container.

    apt update && apt install -y pve-headers-$(uname -r) build-essential dkms
    
    # stop nouveau claiming the card, then reboot
    echo -e 'blacklist nouveau\noptions nouveau modeset=0' > /etc/modprobe.d/blacklist-nouveau.conf
    update-initramfs -u && reboot
    
    # after the reboot — substitute the version you downloaded
    chmod +x NVIDIA-Linux-x86_64-<VERSION>.run
    ./NVIDIA-Linux-x86_64-<VERSION>.run --dkms
    
    nvidia-smi   # should now list the 3090
    Two cards, one decision

    This box has a 3090 and a Quadro RTX 4000. The driver claims both. If the Quadro is doing something else — a VM, display output — check that first, because installing on the host will take it over.

  3. Make the device nodes appear on every boot

    where: proxmox host, as root

    The nodes are created lazily by the first CUDA process, which is no good for a container that expects them at start. Load the modules at boot and keep the driver resident.

    echo -e 'nvidia\nnvidia_uvm\nnvidia_modeset' > /etc/modules-load.d/nvidia.conf
    systemctl enable --now nvidia-persistenced
    
    ls -l /dev/nvidia*   # nvidia0, nvidiactl, nvidia-uvm, nvidia-modeset
  4. Read the real device majors

    where: proxmox host, as root

    Do not copy these numbers from a forum post. nvidia is conventionally 195, but nvidia-uvm is allocated dynamically and differs between machines and reboots-after-upgrade. Read them here and use what you get in the next step.

    grep -E 'nvidia' /proc/devices
    # e.g.  195 nvidia   511 nvidia-uvm   234 nvidia-caps
  5. Bind the GPU into CT 211

    where: proxmox host, as root · passthrough route only

    Append to /etc/pve/lxc/211.conf, substituting the majors from step 4 for the 195 and 511 below.

    lxc.cgroup2.devices.allow: c 195:* rwm
    lxc.cgroup2.devices.allow: c 511:* 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-uvm-tools dev/nvidia-uvm-tools none bind,optional,create=file
    lxc.mount.entry: /dev/nvidia-modeset dev/nvidia-modeset none bind,optional,create=file

    Then give the container somewhere to put 20 GB of weights, and restart it:

    # either grow the root disk…
    pct resize 211 rootfs +60G
    
    # …or mount host storage in, which keeps models off the container disk
    pct set 211 -mp0 /rpool/models,mp=/opt/models
    
    pct stop 211 && pct start 211
  6. Install the matching driver inside the container

    where: inside CT 211, as root · passthrough route only

    Same version as the host, and crucially --no-kernel-module: the container shares the host kernel and must not try to build its own.

    ./NVIDIA-Linux-x86_64-<SAME-VERSION>.run --no-kernel-module
    
    nvidia-smi   # the 3090, from inside the container
    Version skew is the failure mode

    If the host driver updates and the container's does not, nvidia-smi inside starts failing with a mismatch error and every CUDA call dies. Pin both, or use the serve-over-HTTP route and never think about it again.

  7. Run the model

    where: wherever the GPU now works

    Ollama is the least ceremony. Point its model directory at the big disk, expose it on the LAN if this container is going to call it, then pull the model from the next section.

    curl -fsSL https://ollama.com/install.sh | sh
    
    # store weights off the root disk, and listen beyond localhost
    mkdir -p /etc/systemd/system/ollama.service.d
    cat > /etc/systemd/system/ollama.service.d/override.conf <<'EOF'
    [Service]
    Environment="OLLAMA_MODELS=/opt/models"
    Environment="OLLAMA_HOST=0.0.0.0:11434"
    EOF
    systemctl daemon-reload && systemctl restart ollama
    
    ollama pull devstral:24b
    ollama run devstral:24b "write a bash one-liner that lists open ports"
    Then tell me the address

    Once it answers, give me the endpoint — http://192.168.40.x:11434 — and I can call it from this session over HTTP without any of the above being true in here.

The model

What fits in 24 GB, and what it costs you

The trade is not really parameter count — it is how much VRAM is left for KV cache once the weights are loaded. An agent carrying a long context needs that headroom more than it needs another few billion parameters.

Before you pull anything

This container has 13 GB free. Every model above is larger than that, so step 5's disk work is not optional on the passthrough route — and is irrelevant on the serve-over-HTTP route, which is one more reason to prefer it.

The last mile

Pointing Claude Code at it

Claude Code speaks the Anthropic API, and Ollama does not. Bridging them means putting an Anthropic-compatible proxy in front — LiteLLM is the usual choice — and setting ANTHROPIC_BASE_URL at it. It works, it is not an officially supported configuration, and you should expect to debug tool-call formatting rather than have it work first try.

Worth knowing before you spend an evening on it

A 24B model on a 3090 is a large step down from what you are running now, particularly on long agentic tasks — which is exactly the workload you would be pointing it at. It is a genuinely good setup for private, offline, or high-volume work. It is not a cost-saving swap you will be happy with.