Proxmox AI Datacenter

MSN-001 · 2025 · proxmox, llm, docker, gpu

Home lab running on Proxmox — LXC containers and VMs for LLM inference, monitoring, and general compute.

One box handling everything: gaming Windows VM, LLM inference at 75 t/s, Nextcloud, monitoring stack. Built around a Ryzen 7 7700 in a Jonsbo N5 NAS case, with an AMD Instinct MI50 doing the inference work and an RX 6900 XT passed through to Windows.

Why Proxmox

Type-1 hypervisor, open source, web UI that doesn't require memorising qemu flags every time I want to resize a disk. The bigger reason was native LXC support alongside full VMs — most of my workloads are Linux services that don't need full hardware emulation, and containers are noticeably lighter and faster to clone than VMs. Running both on the same host without extra tooling was the main draw.

Hardware

- Ryzen 7 7700 — 8 cores, 3.8 GHz base / 5.4 GHz boost - ASUS ProArt X670E-CREATOR — 8/8 PCIe bifurcation for dual GPU - AMD Instinct MI50 — 32 GB HBM2, gfx906 (LLM inference) - AMD Radeon RX 6900 XT — PCIe passthrough to Windows VM - 3 TB NVMe (Proxmox root + guest disks) - 4 TB HDD (Nextcloud bulk storage) - Jonsbo N5 NAS case

Jonsbo N5 build — MI50 and RX 6900 XT installed, X670E ProArt board, Lexar DDR5

The GPU split

The RX 6900 XT went to the Windows VM via PCIe passthrough — exclusive ownership, the card disappears from the host entirely when Windows boots. That left the MI50 and the CPU iGPU for all the Linux workloads.

Sharing the MI50 between LXC containers is simpler than it sounds. Both `ubuntu-llm` and `ubuntu-ai` get it via bind-mount — the host exposes `/dev/dri` and `/dev/kfd` directly into each container. ROCm doesn't need kernel modules in the guest; it talks to the host `amdgpu` driver through those character devices. The RX 6900 XT couldn't follow the same route — the NVIDIA-style ownership model applies here too, but with AMD's guest passthrough limitations meaning direct container sharing was impractical for gaming workloads. Passthrough was the only option that let Windows own the card cleanly.

Getting ROCm working inside a privileged LXC container required manually setting cgroup device permissions for `/dev/dri/renderD128` and `/dev/kfd`. Proxmox doesn't configure this automatically. I baked the permissions into a base template — new AI containers clone from it and have GPU access from first boot.

What runs on it

- `ubuntu-llm` — llama.cpp inference, shared MI50, 32 GB RAM. Runs Qwen-VL-30B-A3B at 75 t/s. - `ubuntu-ai` — AI dev environment, shared MI50, 8 GB RAM. - `nextcloud` — file storage and sync. 256 GB NVMe OS/DB, 4 TB spinner for files. - `nginxproxymanager` — reverse proxy and TLS. - `influxdb` + `grafana` — time series metrics and dashboards watching the whole stack. - Windows (stopped) — gaming, GTX 1080 Ti passthrough, 16 GB RAM. Starts on demand.

Tailscale runs on the host as both an exit node and a subnet router. Every device on the Tailnet can reach any guest without VPN config in the guests. The Proxmox web UI is behind Tailscale only, never exposed to the LAN bridge.

PCIe passthrough config

The RX 6900 XT is passed through with IOMMU group isolation. Getting the MI50 onto the same board without the groups fighting each other required the X670E ProArt's 8/8 bifurcation mode — without it, the second slot drops to x4 electrical, which causes DMA errors under heavy inference load.

# VM 100 — Windows gaming, RX 6900 XT passthrough
qm set 100 --hostpci0 01:00,pcie=1
The MI50 share between ubuntu-llm and ubuntu-ai hasn't caused contention — they don't run inference simultaneously in practice. The template approach paid off: ubuntu-ai-template-v2 has been cloned twice, both times with GPU access working on first boot with no manual config.

Stack

- Proxmox VE 9.1.1 - ROCm 7.8.0 (host driver, bind-mounted into LXC) - llama.cpp (ROCm backend, gfx906 target) - LXC containers: ubuntu-llm, ubuntu-ai, nextcloud, nginxproxymanager - VMs: Windows (RX 6900 XT passthrough) - InfluxDB + Grafana (monitoring) - Tailscale (remote access + subnet routing)