docs: remove bind-propagation=shared, document runc v1.3.5 crash
runc v1.3.5 (Docker 29.x / Unraid 7.3+) crashes on bind-propagation=shared with any container — not GPU-specific. Ramdisk tmpfs is already MS_SHARED at kernel level; propagation is automatic and the option is unnecessary. - Remove bind-propagation=shared from all example Extra Parameters - Update "Why shared Is Required" → "Mount Propagation — Unraid 7.3+" - Update GPU troubleshooting section to cover the general runc crash - Verify commands updated (no longer checking for Propagation: shared) - Historical notes preserved explaining why it existed before Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
cd2fd1af70
commit
cbf8593225
@@ -45,18 +45,22 @@ suppressed.
|
||||
### Required Mount
|
||||
|
||||
Everything goes in the unRAID Docker template **Extra Parameters** field. Do NOT use the
|
||||
path mapping UI for the transcode directory — it does not support `bind-propagation`.
|
||||
path mapping UI for the transcode directory — it does not support `--mount` syntax.
|
||||
|
||||
**Non-GPU containers:**
|
||||
```
|
||||
--mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode,bind-propagation=shared
|
||||
--mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode
|
||||
```
|
||||
|
||||
**GPU-accelerated containers (Emby, Jellyfin with NVENC/NVDEC):**
|
||||
```
|
||||
--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=GPU-62e1659d-1ed4-935f-3df3-4bb4339438f1" --pids-limit=0 --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode
|
||||
```
|
||||
|
||||
> ⚠️ **Unraid 7.3+ / Docker 29.x / runc v1.3.5+:** Do NOT add `bind-propagation=shared`.
|
||||
> runc v1.3.5 crashes on it with `open /proc/self/mountinfo: no such file or directory`.
|
||||
> The ramdisk tmpfs is already `MS_SHARED` at the kernel level — propagation is automatic.
|
||||
|
||||
Replace the UUID with your GPU's UUID (`nvidia-smi -L` to find it).
|
||||
In Emby and Jellyfin's transcoding settings, set the transcode path to `/ext-ram-transcode`.
|
||||
|
||||
@@ -70,39 +74,37 @@ There are two ways to give a container GPU access. **Always use `--gpus`.**
|
||||
at the Docker daemon level and spreads across multiple XML fields (runtime flag +
|
||||
`NVIDIA_VISIBLE_DEVICES` env var + `NVIDIA_DRIVER_CAPABILITIES` env var). When unRAID
|
||||
rebuilds a container from template (update, reinstall) these fields can break or get dropped
|
||||
— requiring manual XML repair to recover. `--runtime=nvidia` combined with
|
||||
`NVIDIA_VISIBLE_DEVICES` also conflicts with `bind-propagation=shared` on unRAID 7.2.5+
|
||||
due to a kernel change in mount namespace initialization (see
|
||||
[Troubleshooting](#emby-with-nvidia-gpu--bind-propagationshared-fails-to-start) for the
|
||||
full error and fix).
|
||||
— requiring manual XML repair to recover. `--runtime=nvidia` combined with `NVIDIA_VISIBLE_DEVICES` breaks on container rebuilds
|
||||
and has historically conflicted with bind mount propagation settings.
|
||||
|
||||
`--gpus "device=UUID"` is Docker-native GPU support (Docker 19.03+). One field in Extra
|
||||
Parameters. Pins a specific GPU by UUID — no ambiguity on a single-GPU system. Survives
|
||||
container rebuilds cleanly. Does not conflict with `bind-propagation=shared`.
|
||||
container rebuilds cleanly.
|
||||
|
||||
**HOST1 GPU UUID (Quadro P2000):** `GPU-62e1659d-1ed4-935f-3df3-4bb4339438f1`
|
||||
|
||||
### Why `shared` Is Required
|
||||
### Mount Propagation — Unraid 7.3+ / Docker 29.x
|
||||
|
||||
```
|
||||
rprivate (Docker's default):
|
||||
Docker resolves the symlink target at first mount and locks that inode.
|
||||
Flip: ramdisk → SSD → works (new target locked in)
|
||||
Flip: SSD → ramdisk → Docker ignores it. Container still sees SSD binding.
|
||||
All sessions continue to land on SSD forever until Emby restarts.
|
||||
Symptom: symlink on host is correct, Emby still uses SSD. Confusing.
|
||||
> **Do NOT use `bind-propagation=shared`** on Unraid 7.3+ (Docker 29.x / runc v1.3.5+).
|
||||
> runc v1.3.5 rejects it with `open /proc/self/mountinfo: no such file or directory` and
|
||||
> the container fails to start. This applies to all containers — GPU and non-GPU alike.
|
||||
|
||||
shared:
|
||||
Host mount changes propagate into the container in real time.
|
||||
Every symlink flip is immediately visible inside the container. ✅
|
||||
```
|
||||
The ramdisk tmpfs is mounted `MS_SHARED` at the kernel level (`shared:N` in
|
||||
`/proc/self/mountinfo`). Bind mounts from it inherit shared propagation automatically —
|
||||
specifying it in Docker is redundant and breaks on runc v1.3.5+.
|
||||
|
||||
**Historical context (Unraid ≤ 7.2.5):** `bind-propagation=shared` was required
|
||||
because Docker's default `rprivate` resolves the symlink target at mount time and locks
|
||||
that inode, making subsequent flips invisible to the container. On Unraid 7.3+ this
|
||||
option crashes container start entirely. The ramdisk's kernel-level MS_SHARED makes it
|
||||
unnecessary.
|
||||
|
||||
### Verify the Mount
|
||||
|
||||
```bash
|
||||
# Check propagation — must show "shared":
|
||||
# Check the mount is present:
|
||||
docker inspect Emby | grep -A4 "ext-ram"
|
||||
# Expected: "Propagation": "shared"
|
||||
# Expected: "Destination": "/ext-ram-transcode"
|
||||
|
||||
# Check Emby's transcode path setting:
|
||||
docker exec Emby cat /config/config/encoding.xml | grep TranscodingTempPath
|
||||
@@ -417,17 +419,18 @@ Do NOT schedule transcode_manager.sh or transcode_cleanup.sh directly.
|
||||
### Sessions Landing on SSD Despite Symlink Pointing at Ramdisk
|
||||
|
||||
```bash
|
||||
# Check 1 — Docker mount propagation (most common cause):
|
||||
docker inspect Emby | grep Propagation
|
||||
# Expected: "Propagation": "shared"
|
||||
# Wrong: "Propagation": "rprivate"
|
||||
# Check 1 — Docker mount is present:
|
||||
docker inspect Emby | grep -A4 "ext-ram"
|
||||
# Expected: "Destination": "/ext-ram-transcode"
|
||||
# Wrong: no ext-ram-transcode entry
|
||||
#
|
||||
# Fix: Update Emby Extra Parameters, restart Emby.
|
||||
# GPU containers (full string):
|
||||
# --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=GPU-62e1659d-1ed4-935f-3df3-4bb4339438f1" --pids-limit=0 --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode
|
||||
# Non-GPU (mount only):
|
||||
# --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode,bind-propagation=shared
|
||||
# --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode
|
||||
# Remove any standard path mapping for the transcode directory.
|
||||
# Do NOT add bind-propagation=shared — runc v1.3.5+ (Docker 29.x, Unraid 7.3+) rejects it.
|
||||
|
||||
# Check 2 — transcoding-temp exists on ramdisk:
|
||||
ls /mnt/ramdisk_transcodes/
|
||||
@@ -505,8 +508,8 @@ leave the container in a broken state where Emby refuses to start at all.
|
||||
# 1. Remove the entire Extra Parameters line from Emby in unRAID Docker UI
|
||||
# 2. Start Emby and wait for it to fully load (check the WebUI is responsive)
|
||||
# 3. Add the full Extra Parameters line back:
|
||||
# GPU: --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
|
||||
# Non-GPU: --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode,bind-propagation=shared
|
||||
# GPU: --gpus "device=GPU-62e1659d-1ed4-935f-3df3-4bb4339438f1" --pids-limit=0 --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode
|
||||
# Non-GPU: --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode
|
||||
# 4. Save changes and restart Emby
|
||||
#
|
||||
# The container starts cleanly without the mount, which clears the broken state.
|
||||
@@ -587,13 +590,10 @@ assign. Always confirm VRAM is actually free before troubleshooting container GP
|
||||
|
||||
---
|
||||
|
||||
### Emby With NVIDIA GPU — bind-propagation=shared Fails to Start
|
||||
### Container Fails to Start — open /proc/self/mountinfo: no such file or directory
|
||||
|
||||
> **Regression:** This worked before unRAID 7.2.5. The kernel update changed how mount
|
||||
> namespaces are initialized, exposing a conflict in the NVIDIA container runtime path.
|
||||
|
||||
`--runtime=nvidia` combined with a `NVIDIA_VISIBLE_DEVICES` environment variable conflicts
|
||||
with `bind-propagation=shared`. Docker fails during container init with:
|
||||
> **Unraid 7.3+ / Docker 29.x / runc v1.3.5+** — any container with `bind-propagation=shared`
|
||||
> in Extra Parameters crashes with this error. Not GPU-specific — affects all containers.
|
||||
|
||||
```
|
||||
OCI runtime create failed: runc create failed: unable to start container process:
|
||||
@@ -601,28 +601,24 @@ error during container init: error jailing process inside rootfs:
|
||||
open /proc/self/mountinfo: no such file or directory
|
||||
```
|
||||
|
||||
`--runtime=nvidia` alone (no `NVIDIA_VISIBLE_DEVICES` env var) does NOT cause this.
|
||||
The conflict requires both.
|
||||
**Root cause:** runc v1.3.5 tries to read `/proc/self/mountinfo` inside the new mount
|
||||
namespace before `/proc` is mounted, crashing when `bind-propagation=shared` is present.
|
||||
|
||||
**Root cause:** `NVIDIA_VISIBLE_DEVICES` triggers the NVIDIA container runtime to bind
|
||||
mount CUDA libraries and device nodes into the container namespace. This GPU device setup
|
||||
interferes with the mount namespace initialization that `bind-propagation=shared` requires.
|
||||
**Fix:** Remove `bind-propagation=shared` from Extra Parameters entirely.
|
||||
|
||||
**Fix — replace the NVIDIA env var approach with the `--gpus` flag:**
|
||||
In the unRAID Docker template:
|
||||
|
||||
In the unRAID Docker template for Emby:
|
||||
|
||||
1. **Extra Parameters** — remove `--runtime=nvidia`, replace with the full line:
|
||||
1. **Extra Parameters** — remove `bind-propagation=shared` from the `--mount` option:
|
||||
```
|
||||
--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=GPU-62e1659d-1ed4-935f-3df3-4bb4339438f1" --pids-limit=0 --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode
|
||||
```
|
||||
|
||||
2. **Variables** — remove the `NVIDIA_VISIBLE_DEVICES` variable entirely.
|
||||
The `--gpus` flag handles GPU assignment without the env var.
|
||||
2. The ramdisk tmpfs is already `MS_SHARED` at the kernel level (`shared:N` in
|
||||
`/proc/self/mountinfo`). Propagation is inherited automatically — no Docker flag needed.
|
||||
|
||||
`--gpus "device=UUID"` uses Docker's native GPU device flag (default runtime) rather than
|
||||
the full NVIDIA container runtime setup. The container still gets GPU access; it just
|
||||
skips the device mount phase that conflicts with `bind-propagation=shared`.
|
||||
**Historical note:** On Unraid ≤ 7.2.5 (Docker <29.x), `bind-propagation=shared` was
|
||||
required for symlink flips to propagate into running containers. On Unraid 7.3+ it crashes
|
||||
container start. The kernel-level MS_SHARED on the tmpfs makes it unnecessary.
|
||||
|
||||
### Increasing Ramdisk Size After Initial Setup
|
||||
|
||||
|
||||
@@ -6,16 +6,15 @@ without interrupting anything already playing. When pressure drops, new sessions
|
||||
back to RAM.
|
||||
|
||||
> **Three configuration requirements that are not obvious and were all discovered the
|
||||
> hard way in production.** The Docker mount must use `bind-propagation=shared` or
|
||||
> symlink flips are silently ignored after the first flip. The `transcoding-temp`
|
||||
> directory must be pre-created on the ramdisk or Emby finds the SSD version and
|
||||
> routes all sessions there until restarted. GPU containers require `--gpus "device=UUID"`
|
||||
> in Extra Parameters — not `--runtime=nvidia` — or the container fails to start after
|
||||
> unRAID 7.2.5. Additionally: any GPU-accelerated sidecar (OCR plugins, credit detection)
|
||||
> that holds VRAM and never releases it will starve Emby and Jellyfin of VRAM for
|
||||
> transcoding — Jellyfin hard-fails, Emby silently falls back to CPU. Emby's startup
|
||||
> NVIDIA probe is one-shot: if VRAM is exhausted when the container starts, NVIDIA stays
|
||||
> disabled for the entire session. All three are documented in Manual-Transcoding.md.
|
||||
> hard way in production.** The `transcoding-temp` directory must be pre-created on
|
||||
> the ramdisk or Emby finds the SSD version and routes all sessions there until
|
||||
> restarted. GPU containers require `--gpus "device=UUID"` in Extra Parameters —
|
||||
> not `--runtime=nvidia`. Do **not** use `bind-propagation=shared` on Unraid 7.3+
|
||||
> (Docker 29.x / runc v1.3.5+) — it crashes container start; the ramdisk is already
|
||||
> MS\_SHARED at the kernel level. Additionally: any GPU-accelerated sidecar (OCR plugins,
|
||||
> credit detection) that holds VRAM and never releases it will starve Emby and Jellyfin
|
||||
> of VRAM for transcoding — Jellyfin hard-fails, Emby silently falls back to CPU.
|
||||
> All three are documented in Manual-Transcoding.md.
|
||||
|
||||
---
|
||||
|
||||
@@ -24,21 +23,20 @@ back to RAM.
|
||||
> **Stop. Set this before starting Emby or Jellyfin. If you Google how to add GPU
|
||||
> access to a Docker container on unRAID you will find the wrong answer.** Every
|
||||
> forum post and guide shows `--runtime=nvidia` + `NVIDIA_VISIBLE_DEVICES`. That
|
||||
> method conflicts with `bind-propagation=shared` on unRAID 7.2.5+ and breaks on
|
||||
> container rebuilds. Use `--gpus` instead.
|
||||
> method breaks on container rebuilds. Use `--gpus` instead.
|
||||
|
||||
In the unRAID Docker template, open **Advanced View** and paste the following into
|
||||
the **Extra Parameters** field. Do not use the path mapping UI for the transcode
|
||||
directory — it does not support `bind-propagation`.
|
||||
directory — it does not support the `--mount` syntax.
|
||||
|
||||
**GPU-accelerated (Emby, Jellyfin with NVENC/NVDEC) — use this:**
|
||||
```
|
||||
--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=GPU-62e1659d-1ed4-935f-3df3-4bb4339438f1" --pids-limit=0 --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode
|
||||
```
|
||||
|
||||
**Non-GPU — use this:**
|
||||
```
|
||||
--mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode,bind-propagation=shared
|
||||
--mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode
|
||||
```
|
||||
|
||||
In Emby and Jellyfin's transcoding settings, set the transcode temp path to `/ext-ram-transcode`.
|
||||
@@ -66,14 +64,13 @@ Fix: symlink indirection. Emby points at a fixed path. The symlink target change
|
||||
ffmpeg resolves the symlink once at session start — existing sessions are completely
|
||||
unaffected by flips. Only new sessions follow the new target.
|
||||
|
||||
**Docker Bind Mount Silently Ignored After First Flip**
|
||||
**Docker Bind Mount Silently Ignored After First Flip** *(historical — resolved differently)*
|
||||
Symlink flip from ramdisk → SSD worked. Flip back: nothing. All new sessions still land
|
||||
on SSD. The symlink on the host is correct. Emby doesn't see it.
|
||||
Cause: Docker's default `rprivate` propagation resolves the symlink target at mount time
|
||||
and locks that inode. Subsequent flips are invisible to the container.
|
||||
Fix: `bind-propagation=shared` in Extra Parameters. Host mount changes propagate into
|
||||
the container in real time. Requires `--mount` syntax — the path mapping UI doesn't
|
||||
support propagation.
|
||||
Original fix was `bind-propagation=shared` — but this crashes runc v1.3.5+ (Docker 29.x,
|
||||
Unraid 7.3+) on any container start. The ramdisk tmpfs is `MS_SHARED` at the kernel level,
|
||||
so propagation is inherited automatically without specifying it in Docker. Do not add
|
||||
`bind-propagation=shared` to Extra Parameters.
|
||||
|
||||
**Sessions Drifting to SSD After a Day of Operation**
|
||||
System working correctly for hours, then sessions gradually drift to SSD despite the
|
||||
|
||||
Reference in New Issue
Block a user