Plex Hardware Transcoding on Nixos (Docker Compose)
Plex Hardware Transcoding on NixOS (Docker)
The Problem
Plex running in Docker on a NixOS host could detect the Nvidia GPU (via nvidia-smi) but failed to use it for transcoding. The dashboard showed software transcoding (high CPU usage), and logs reported [TPU] hardware transcoding: enabled, but no hardware decode accelerator found.
The Root Causes
- Driver Injection (CDI): NixOS uses the newer CDI (Container Device Interface) method, requiring specific
deployblocks rather than the legacygpus: allflag. - Permissions: The container user (
PUID=1000) lacked permission to access the Direct Rendering Manager (DRM) nodes (/dev/dri/card0and/dev/dri/renderD128). - Library Paths: The Nvidia driver libraries (e.g.,
libnvcuvid.so) were injected into non-standard paths on NixOS (/usr/local/nvidia/lib64), which Plex does not check by default.
The Solution
1. NixOS Host Configuration (configuration.nix)
Ensure the host has graphics enabled and the Nvidia container toolkit active.
hardware.graphics.enable = true;
hardware.nvidia.modesetting.enable = true;
hardware.nvidia-container-toolkit = {
enable = true;
mount-nvidia-executables = true;
};
**2. Final Working docker-compose.yml**
This configuration addresses the driver injection, permission groups, and library paths.
services:
plex:
image: lscr.io/linuxserver/plex:latest
container_name: plex
network_mode: host
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
- VERSION=docker
# 1. Enable Driver Capabilities
- NVIDIA_VISIBLE_DEVICES=all
- NVIDIA_DRIVER_CAPABILITIES=all
# 2. Force Plex to check NixOS/CDI library paths
- LD_LIBRARY_PATH=/usr/lib/plexmediaserver/lib:/usr/local/nvidia/lib:/usr/local/nvidia/lib64:/usr/lib:/usr/lib64
# 3. Grant access to host hardware groups
# Run `getent group render` and `getent group video` on host to confirm IDs.
group_add:
- "303" # render group (for /dev/dri/renderD128)
- "26" # video group (for /dev/dri/card0)
volumes:
- ./Library:/config/Library
# 4. Map the hardware device nodes
- /dev/dri:/dev/dri
# ... (media volumes)
restart: unless-stopped
# 5. Use CDI for GPU resource allocation
deploy:
resources:
reservations:
devices:
- driver: cdi
device_ids:
- nvidia.com/gpu=0
capabilities: [gpu]
Troubleshooting Commands
If the GPU fails again, use these commands to diagnose where the chain is broken:
- Check GPU Visibility:
docker exec -it plex nvidia-smi
- Check Permissions:
docker exec -it plex ls -ln /dev/dri
# Ensure the group IDs match what you set in group_add
- Find Missing Libraries:
docker exec -it plex find / -name "libnvcuvid.so*"
# If found in /usr/local/nvidia/lib64, ensure LD_LIBRARY_PATH includes it.