Add GPU containers section to main README — ignore Google

Every search result shows --runtime=nvidia which conflicts with
bind-propagation=shared on unRAID 7.2.5+ and breaks on container
rebuilds. New prominent section explains the correct --gpus approach,
why the old method fails, and the VRAM starvation cascade.

Item #6 in Surprises updated to reference the new section; arr cleanup
renumbered to #8.
This commit is contained in:
Gmer4Lfe
2026-05-23 14:19:56 -04:00
parent 1381540dab
commit 921e137d95
+89 -2
View File
@@ -681,6 +681,89 @@ Problem: HOST1 loses power
---
## ━━━ GPU CONTAINERS — IGNORE GOOGLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
> **Every tutorial, forum post, and Reddit thread shows the wrong way to add GPU
> access to a Docker container on unRAID.** The old method breaks silently in ways
> that are very hard to diagnose. Read this before touching any GPU container.
### The Wrong Way (What Google Shows)
```bash
# DO NOT DO THIS
Extra Parameters: --runtime=nvidia
Variables: NVIDIA_VISIBLE_DEVICES=GPU-xxxxxxxx
NVIDIA_DRIVER_CAPABILITIES=compute,video,utility
```
This is `--runtime=nvidia` — the old NVIDIA Container Toolkit approach. It is what
every guide written before Docker 19.03 recommends. It still shows up in official
unRAID forum posts, community applications templates, and most search results.
**Why it breaks here:**
1. `--runtime=nvidia` combined with `NVIDIA_VISIBLE_DEVICES` conflicts with
`bind-propagation=shared` on unRAID 7.2.5+. A kernel change in mount namespace
initialization exposed a conflict between the NVIDIA device mount phase and shared
propagation setup. The container fails to start with:
```
OCI runtime create failed: unable to start container process:
error jailing process inside rootfs:
open /proc/self/mountinfo: no such file or directory
```
This system uses `bind-propagation=shared` for the transcode ramdisk mount.
Emby and Jellyfin both require it. The old nvidia method makes them incompatible.
2. When unRAID rebuilds a container from template (update, reinstall from Community
Applications), the `--runtime=nvidia` field and the NVIDIA env vars can be dropped
or corrupted. Rebuilding a container is a normal maintenance operation — it should
not break GPU access. With the old method, it sometimes does.
### The Right Way
```bash
# DO THIS — everything in Extra Parameters, nothing in Variables
--gpus "device=GPU-62e1659d-1ed4-935f-3df3-4bb4339438f1" --pids-limit=0 --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode,bind-propagation=shared
```
`--gpus "device=UUID"` is Docker-native GPU support (Docker 19.03+, released 2019).
One field in Extra Parameters. The UUID pins a specific device — no ambiguity on
single-GPU systems. No env vars needed. No `--runtime=nvidia`. No conflict with
`bind-propagation=shared`. Survives container rebuilds. This is the correct method.
Find your GPU UUID: `nvidia-smi -L`
**HOST1 GPU UUID (Quadro P2000):** `GPU-62e1659d-1ed4-935f-3df3-4bb4339438f1`
### GPU Memory and Media Servers
A failure mode that is extremely non-obvious and not documented anywhere:
Any container that uses VRAM and does not release it will starve Emby and Jellyfin
of the GPU memory they need to start transcoding sessions. The two media servers
respond differently:
- **Jellyfin:** hard fails — no session is created, playback stops entirely
- **Emby:** falls back to CPU transcoding silently and keeps going
The non-obvious source is OCR sidecars — credit detection plugins, subtitle
extraction tools — that talk to a GPU-accelerated OCR container. PaddleOCR in
particular loads a neural network into VRAM at first use and does not release it
between runs. One credit scan, and VRAM stays consumed until the container restarts.
**Emby startup probe:** Emby runs a one-shot NVIDIA hardware detection at container
start. If VRAM is exhausted when Emby starts, NVIDIA is marked unavailable for the
entire session — no retry. Restarting Emby while VRAM is still full just fails the
probe again. Correct recovery: free VRAM first, confirm with `nvidia-smi`, then
restart Emby.
For the EmbyCredits plugin: use the `yock1/embycreditocr` Tesseract image (port 8884,
CPU-based) instead of PaddleOCR. Same plugin, no VRAM.
**→ Full detail: [Manual-Transcoding.md](Transcodes/Manual-Transcoding.md)**
---
## ━━━ SETUP — WHERE TO START ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
If you're setting this up from scratch on two servers:
@@ -752,12 +835,16 @@ Things that are different from what you might expect:
# HOST*_ vars based on the running server. The same script runs correctly on
# HOST1 and HOST2 — no branching on server identity inside scripts.
# 6. The Emby Docker mount is unusual and critical.
# 6. GPU containers: ignore every Google result. Use --gpus, not --runtime=nvidia.
# --runtime=nvidia conflicts with bind-propagation=shared on unRAID 7.2.5+.
# It also breaks on container rebuilds. See GPU CONTAINERS section above.
# 7. The Emby Docker mount is unusual and critical.
# --mount type=bind,...,bind-propagation=shared in Extra Parameters — not a
# standard path mapping. Without shared propagation symlink flips are silently
# ignored. README-Transcoding.md explains why in detail.
# 7. arr cleanup scripts can delete files.
# 8. arr cleanup scripts can delete files.
# lidarr_cleanup.sh, sonarr_cleanup.sh, radarr_cleanup.sh permanently delete
# orphaned files. Safety layers prevent catastrophic runs but always test with
# --dry-run --log first on a new system. README-Media.md has the full procedure.