Skip to content

Plex

Plex Media Server runs as an LXC container on proxfold.

Container details

Property Value
Container ID 100
Hostname plex
IP 192.168.1.230
OS Debian
Memory 4096 MB
Storage 32G root disk
Mount points mp0: /stash,mp=/stash
mp1: /stash/plex-data,mp=/stash/plex-data

Media access

The ZFS pool is mounted directly into the container at /stash via Proxmox mount point (mp0). A symlink provides the path Plex uses:

/mnt/plex -> /stash/rodneystash

Plex library paths:

Library Path in container
Movies /mnt/plex/Movies
TV Shows /mnt/plex/TV Shows

Plex data directory (ZFS)

The Plex data directory (metadata, databases, cache, transcode sessions, logs) lives on a dedicated ZFS child dataset, not on the container rootfs. This was migrated in April 2026 to prevent the rootfs from filling up during active transcoding.

Architecture

/var/lib/plexmediaserver/Library/Application Support/Plex Media Server
  → symlink → /stash/plex-data

The stash/plex-data dataset is mounted into the container via mp1 and has a 100GB quota. The rootfs now only holds the OS, Plex binaries, and Nvidia drivers (~11GB, essentially static).

What lives on ZFS (stash/plex-data)

  • Metadata/ — posters, artwork, backgrounds
  • Cache/Transcode/Sessions/ — active transcode temp files
  • Cache/PhotoTranscoder/ — device-optimised thumbnails
  • Cache/Shaders/ — GPU shader cache
  • Plug-in Support/Databases/ — library database (most critical)
  • Plug-in Support/Caches/ — agent HTTP caches
  • Logs/ — server logs
  • Codecs/ — downloaded codec packs
  • Preferences.xml — server config

What stays on rootfs

  • Plex binaries at /usr/lib/plexmediaserver/
  • Systemd service file
  • Nvidia driver libraries
  • The OS (Debian packages, kernel, apt cache)
  • The symlink itself

Benefits

  • Independent ZFS snapshots (can snapshot Plex data without snapshotting 7TB of media)
  • Quota enforcement (Plex can never eat into media space)
  • Clean monitoring via zfs list -r stash

Permissions

Plex runs as user plex (uid 999, gid 996). Media files on ZFS are owned by root:root with 755 permissions, which gives Plex read access. The stash/plex-data dataset is owned by 999:996 on the host (privileged container, no uid remapping).

Previous NAS mount (disabled)

The systemd mount unit at /etc/systemd/system/mnt-plex.mount previously mounted the NAS via CIFS. It is stopped and disabled but the unit file still exists on disk:

systemctl stop mnt-plex.mount
systemctl disable mnt-plex.mount

GPU passthrough (Nvidia T400)

The Plex LXC has an Nvidia T400 GPU passed through from the proxfold host for hardware-accelerated transcoding.

LXC configuration

The following is appended to /etc/pve/lxc/100.conf on proxfold:

lxc.cgroup2.devices.allow: c 195:* rwm
lxc.cgroup2.devices.allow: c 234:* rwm
lxc.cgroup2.devices.allow: c 237:* 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-modeset dev/nvidia-modeset 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-caps/nvidia-cap1 dev/nvidia-caps/nvidia-cap1 none bind,optional,create=file
lxc.mount.entry: /dev/nvidia-caps/nvidia-cap2 dev/nvidia-caps/nvidia-cap2 none bind,optional,create=file

Dynamic major numbers — check after every host kernel/driver change

The cgroup2 device major numbers for nvidia-uvm (currently 234) and nvidia-caps (currently 237) are dynamically allocated by the kernel and shift whenever the Nvidia kernel module is rebuilt against a new kernel or reinstalled. Major 195 for nvidia0/nvidiactl/nvidia-modeset is static and rarely changes.

Verify after any host change with ls -la /dev/nvidia* and ls -la /dev/nvidia-caps/ on proxfold, then update /etc/pve/lxc/100.conf and restart the container.

Observed incident (2026-04-19, PVE 8.4 → 9 upgrade): majors shifted from 235→234 (nvidia-uvm) and 238→237 (nvidia-caps). nvidia-smi inside the container still worked (it uses static major 195) so the problem was silent, but Plex dropped to software transcode (libx264) because CUDA calls against /dev/nvidia-uvm were blocked by cgroup. Symptom: Plex dashboard shows transcode active but without the (hw) tag.

Userspace libraries

The container requires Nvidia userspace libraries exactly matching the host driver version (currently 550.163.01). Install inside the container using the same .run installer used on the host (with --no-kernel-module). The host itself uses DKMS so the module is rebuilt automatically on kernel updates; the container has no kernel module of its own. Verify:

nvidia-smi

If nvidia-smi shows the T400 from inside the container, passthrough is working.

Plex settings

  1. Navigate to Settings → Transcoder
  2. Enable Use hardware acceleration when available
  3. Enable Use hardware-accelerated video encoding To verify: play content and force a transcode (set client quality to 720p 4 Mbps). The Plex dashboard should show (hw) next to the session. Monitor GPU usage on the host:
nvidia-smi -l 1

The codified procedure lives in the nvidia role — driver install, keylase NVENC patch, persistence daemon, IPMI fan fix, and LXC passthrough are all handled by ansible-playbook playbooks/proxmox-host.yml --tags nvidia. For bare-metal rebuild context see rebuild.md — Reconstitute the host.