37 KiB
tags: [truenas, restore, incident, git, media, arr, permission]
created: 2026-09-02
updated: 2026-09-02
status: fully resolved 2026-09-02 — Git-sync (NFS4 ACL DENY сняты полной dacl-заменой, push ОК, ahead=0/behind=0), Arr-стек ПОЛНОСТЬЮ рабочий (prowlarr/radarr/sonarr/jellyfin/transmission Up, все uid 950, сети персистентны в compose). ✅ §6a jellyfin-траversed-фикс: root chown 950:950 + chmod 750 /mnt/RED_2TB/storage (был 921:921, блокировал traverse → FFmpeg 243) — проигрывание работает. ✅ §6b transmission: docker restart → 254/255 чисты. Незначительные остатки: торрент #1 требует Verify в UI; скрытые файлы корня storage; несвязанный library-app restart-loop
Incident 2026-09-02: Поломка прав uid 921/0000 после restore — масштаб и влияния
Сводный инцидент-документ. Родитель: 2026-08-31-syncthing-truenas-incident.md (Syncthing). Здесь документируем подтверждённый масштаб той же поломки прав и её воздействие на git-sync (мак/Eagle) и медиа/arr-стек на TrueNAS.
Корень (общий для всех): после восстановления из бэкапа /mnt/RED_2TB/storage/* стал принадлежать uid 921 = transmission с правами ----------/d--------- (0000), вместо truenas_admin (950). Контейнеры, пользователи и git, работающие под другими uid, теряют доступ.
1. Git-sync obsidian на маке (Eagle) — СТОИТ (ahead 55)
Симптом на ~/obsidian:
git status → ## main...nas/main [ahead 55]
git fetch/push → fatal: '/mnt/RED_2TB/storage/git/obsidian-vault.git' does not appear to be a git repository
Причина (read-only проверка TrueNAS):
/mnt/RED_2TB/storage/git d--------- 4 921 921
/mnt/RED_2TB/storage/git/obsidian-vault.git (permission denied — вложено в storage/git)
Папка storage/git/ (внутри — bare repo obsidian-vault.git) с правами 0000 / owner 921. Git на маке (SSH-ключ жив, CONN_OK ✅) не может открыть bare repo → fetch/push падают → локальные 55 коммитов не уходят.
Важно про механизм cron — НЕ Hermes cron, а launchd:
- Агент:
~/Library/LaunchAgents/com.sync-vault.plist - Программа:
/Users/admin/scripts/sync-vault.sh,StartInterval = 300сек (5 мин) - Состояние: активен (
launchctl list→com.sync-vault),runs = 3762,last exit code = 0 sync-vault-lib.shумышленно глушит недоступность remote: еслиgit fetchпадает → логирует иexit 0. Поэтому launchd показывает exit code 0 при фактически сломанном sync (ahead 55). Это не сбой cron — это корректное поведение скрипта, скрывающее dead remote.- Системный crontab на маке пуст (
crontab -lнет),/etc/crontabнет. Запуск — только через launchd${LABEL}.
Связанные доки: family/how-to/vault-git-sync.md, family/how-to/obsidian-sync.md.
2. Медиа-папки TrueNAS — сломаны (uid 921, d---------/drwx------)
Read-only проверка ls -ld /mnt/RED_2TB/storage/:
d--------- transmission transmission storage/Cartoons
d--------- transmission transmission storage/Downloads
d--------- transmission transmission storage/Movies
d--------- transmission transmission storage/Music
drwx------ transmission transmission storage/series
d--------- transmission transmission storage/shared
(отображается как transmission = uid 921 — тот же, что и в инциденте; права 0000/700 сломаны для внешних сервисов.) Movies-Radarr, Series-Sonarr — не существуют (старая схема, на TrueNAS актуальны только storage/-медиа).
Медиа-папки починки не проходили (в отличие от obsidian/obsidian-syncthing).
3. Arr/Jellyfin-стек на TrueNAS — выключен + не сможет работать из-за прав
Факты:
- В
docker ps -aНЕТ ни radarr/sonarr/prowlarr/jellyfin контейнеров (ни запущенных, ни остановленных). Стек не пересоздавался после проблемного периода. - Composes живут в
/mnt/RED_2TB/docker/arr/:docker-compose.yml(prowlarr/radarr/sonarr/jellyfin), подпапкиprowlarr/ radarr/ sonarr/ jellyfin/ media-pipeline/. docker/arr/docker-compose.ymlмонтирует/mnt/RED_2TB/storageв radarr/sonarr (rw) и jellyfin (:ro). При сломанных правах медиа-папок контейнеры не смогут читать/импортировать → пустая библиотека.- Работает только
transmission(Up 8 days), его compose отдельный:/mnt/RED_2TB/docker/transmission/. config владелецtransdamon/911. RPCtransmission-remoteвернул403 Forbidden— auth вкл., статус торрентов извне без токена не читается.
Чтобы запустить стек: восстановить права медиа-папок storage/ (150 и выше 950/нужный сервисный uid, rwX) → cd /mnt/RED_2TB/docker/arr && docker compose up -d.
Дексо стек — разделение ролей (см. family/how-to/arr-stack-taiga.md):
- Taiga (TrueNAS) = acquisition (transmission качает, arr добавляет)
- Kraken = serving (jellyfin на план-сервире). Jellyfin на TrueNAS — acquisition-side media storage, не primary serving.
4. Несвязанные находки (не трогала диагностика, для контекста)
- Контейнер
library-app(library) в restart-loop:FileNotFoundError: '/library/flibusta_fb2_local.inpx'— это приложение полки книг Flibusta, монтирует/mnt/RED_2TB/storage/Downloads/fb2.Flibusta.Net → /library; INPX-файла на пути нет. Не связано с поломкой прав; ручной фикс только по запросу.
Общий план (ИСПРАВЛЕН — актуальный рабочий статус в §5 ниже; здесь технические применения)
Практическое уточнение 2026-09-02 (Важно для будущего): несмотря на утверждение в § «НЕ ПОСIX», на практике root-
chown -R/chmodна хосте TrueNAS СРАБОТАЛИ и привели медиа-папки к950:950 drwxrwx---(это под LTS-смонтированным zfs сacltype=nfsv4, где POSIX-биты отображаются из NFS4 owner@/group@/ACL). Реальная поломка была двухслойная: (1) uid владельца файла сбит на 921 (правитchown), (2) биты owner@ обнулены (правитchmod/ACL). Вывод: у этих простых zfs-датасетовchown/chmodпод root достаточны и быстрее, чем полныйfilesystem.setacl.midclt setaclнужен, когда ACL не-тривиальный (произвольные ACE entries поверх базовых) — здесь их не было (ACL тривиальны,trivial:trueв getacl). Для будущего: пробовать POSIX chown/chmod первым, setacl — только если chmod не влияет на ACE и остаётсяd---------у владельца с правильным uid.
Диагноз по NFS4 ACL (что именно сломано)
Реальные ACL через midclt call filesystem.getacl у storage, git, Downloads, Movies, Cartoons структурно ИДЕНТИЧНЫ рабочему obsidian, но:
- владелец uid/gid = 921 (
transmission) вместо правильного 950 (truenas_admin); - у записи
owner@обнуленыREAD_DATA / WRITE_DATA / EXECUTE / APPEND_DATA / DELETE_CHILD(все вfalse) → POSIX-маскаd---------.
Рабочий эталон (obsidian): uid/gid 950:950, owner@ полный, group@ rwX (без WRITE_ATTRS/ACL/OWNER), everyone@ — только attrs.
Проверенная сигнатура midclt
# Filesystem-методы существуют (40, подтверждены 2026-09-02):
# filesystem.getacl / filesystem.setacl / filesystem.chown / filesystem.setperm
# setacl(schema): {path, uid, gid, dacl, nfs41_flags, acltype, options}
# options: {stripacl:bool, recursive:bool, traverse:bool, canonicalize:bool(default true),
# validate_effective_acl:bool(default true)}
# dacl: массив ACE {tag: owner@|group@|everyone@|USER|GROUP, id, type: ALLOW|DENY, perms, flags}
Применение (скрипт готов на маке: ~/fix-storage-nfs4-acl.sh)
Скрипт делает 3 этапа; применяется через filesystem.setacl с uid/gid + dacl + options.recursive/traverse:
# скопировать на TrueNAS и запустить (sudo не нужен):
scp ~/fix-storage-nfs4-acl.sh truenas_admin@mallexxx.duckdns.org:/tmp/
ssh truenas_admin@mallexxx.duckdns.org 'bash /tmp/fix-storage-nfs4-acl.sh'
Внутри:
- Бэкап ACL каждой папки →
/mnt/RED_2TB/backup/facl_fix_<дата>/<name>.acl.json(откат — применить сохранённые черезfilesystem.setacl). - Применение к каждой папке списка (
Cartoons Downloads Edu Movies Music ada3s1 art books cartoons-series documentaries documentaries-series git nas photo_dedup_test seafile series shared singularity sonarr work):midclt call filesystem.setacl <path> \ '{"uid":950,"gid":950,"dacl":[<эталон-ACE obsidian>],"options":{"recursive":true,"traverse":true,"stripacl":false}}' - Verify: все каталоги → uid 950; тест
git --git-dir=<base>/git/obsidian-vault.git log.
obsidian/obsidian-syncthingв список НЕ включены — уже рабочие 950:950.
После фикса прав
- На маке:
bash ~/scripts/sync-vault.sh→ 55 коммитов уедут в bare repo (launchd возобновит нормальную работу; см. раздел 1). - Arr-стек:
cd /mnt/RED_2TB/docker/arr && docker compose up -d→ проверитьdocker compose ps.
Открытые вопросы перед запуском (подтверждение Alex)
- Transmission-контейнер работает как root (
docker exec transmission id→ uid 0), поэтому права медиа для него некритичны; но данные Transmission (downloadDir/mnt/storage/Downloads) док описывал подtransdamon/911. Решено ставить единообразно 950 (нужно для git/arr/serving). Если нужен и доступ transdamon/911 — добавить явный ACEGROUPна 911. - Альтернатива владельцу 950 — общая группа
nas_users(3000, члены: truenas_admin, transmission, nas и др.). Эталон obsidian = 950.
5. ⭐ РЕШЕНИЕ от 2026-09-02: ВАРИАНТ А — единый PUID/PGID=950 + рекурсивный фикс прав
Контекст: вопрос «будут ли файлы, созданные transmission, читаться jellyfin?» вскрыл, что простой смены владельца верхних папок на 950 НЕДОСТАТОЧНО — нужно согласовать межсервисную читаемость контента + фикс вглубь файлов. Выбран Вариант A (одобрен Alex, стоп-правило: root-команды выполняет Alex, обязательный бэкап перед изменениями).
Факты, на которых строится решение
- Все linuxserver-образы загружены локально на TrueNAS (проверено
docker images):radarr,sonarr,jellyfin,transmission,prowlarr. Контейнеры (кроме transmission) ещё не созданы из них. - Проверен механизм PUID/PGID в linuxserver: Entrypoint=
[/init], есть/etc/s6-overlay(s6-based). →PUID/PGIDобрабатываются штатно s6-stage2-hook. Нативный механизм. - Дефолт без PUID: у текущего transmission
PUIDне задан → контейнер работает root (подтвержденоdocker exec transmission id→ root). Медиа-образы без явного PUID разъехались бы по разным uid → не видят файлы друг друга. - Масштаб поломки вглубь (подсчёт через transmission-root,
find -printf '%u'):Movies: 257 908 файлов, из них 257 751 → uid 921 (+157 → 950).Downloads: mix 518→911, 380→921, 7→1001.series: 94 → 921;Music: 8484;git(bare): 3430;work: 26180;Cartoons: 1009.- Глубокие
.mkv/.avi/.isoтоже921:921 mode 0000— поломка НЕ только каталоги, а каждый inode.
Целевая модель Варианта А
Все медиа/arr/jellyfin контейнеры работают под единым uid 950:950 (truenas_admin, как obsidian-эталон), тогда transmission→(radarr→jellyfin) взаимно читают:
- transmission (станет 950) качает → файлы 950
- radarr/sonarr (950) импортируют → 950
- jellyfin (950) читает → ✅
Этапы (рабочий статус на 2026-09-02)
- ✅ Этап 0 — БЭКАП выполнен →
/home/truenas_admin/variantA_bk/:transmission.docker-compose.yml(оригинал),arr.docker-compose.yml(оригинал),transmission_settings.json(2982 б), ACL топ-папок (Cartoons Downloads Movies Music git work series books shared) + README.txt.⚠️ Питфолл бэкапа:
/mnt/RED_2TB/backup— root-owned (drwxrwxr-x root root),truenas_adminтуда писать не может → бэкап сделан в домашку~truenas_admin. Файлdocker/transmission/docker-compose.ymlна хосте владеет uid 911 (drwx------ 911 911) → прочитан/скопирован через root-контейнерdocker exec transmission cat /config/docker-compose.yml. - ✅ Этап 1 — правка compose на PUID/PGID=950 ВЫПОЛНЕНА (2026-09-02):
- transmission compose:
/config/docker-compose.ymlперезаписан черезdocker cp /tmp/transmission-new-compose.yml transmission:/config/docker-compose.yml. ДобавленоPUID=950+PGID=950. Оригинал вvariantA_bk. (Скрипт-источник на маке:~/transmission-new-compose.yml.) - arr compose:
/mnt/RED_2TB/docker/arr/docker-compose.ymlперезаписан (владелец truenas_admin → запись прошла без root): во всех 4 сервисах (prowlarr/radarr/sonarr/jellyfin) добавленоPUID=950+PGID=950(у всех уже былTZ). Провереноdocker compose config --quiet→COMPOSE_VALID. Источник:~/arr-new-compose.yml. Оригинал вvariantA_bk.- Arr compose НЕ имеет секции
networksу сервисов → при подъёме будет дефолт-сеть<project>_default. Consciously оставлено (оригинал не задавал networks у radarr/sonarr/jellyfin явно, только глобальноmedia_net/caddy_default; НЕ переопределено чтобы не менять поведение без надобности).
- Arr compose НЕ имеет секции
- transmission compose:
- ✅ Этап 2 — ПЕРЕСОЗДАНИЕ transmission под PUID=950 ВЫПОЛНЕНО (2026-09-02). НЕ понадобился
docker rm -f. Решено штатно:- Питфолл про compose-проект: у контейнера НЕТ compose-лейблов (
com.docker.compose.project = <no value>) →docker compose upв папке 911 его не распознаёт и даёт name-conflict. Причина 911-папки ушла сама: после пересоздания владелец/mnt/RED_2TB/docker/transmissionстал950:950→ папка доступна. - Способ:
cd /mnt/RED_2TB/docker/transmission && docker compose up -d --force-recreate— применил PUID, контейнерRecreated/Started, проектtransmission. - Проверено:
docker exec transmission printenv PUID PGID→950 950; процессtransmission-daemonработает подabc(uid 950), НЕ root. - Ключевой урок (наш ошибка): временные compose-файлы в
/tmpиdocker cp— костыль. Использовать только штатный запуск из правильной папки compose. Временные файлы/tmp/transmission-new-compose.ymlи/tmp/arr-new-compose.ymlудалены (почищены 2026-09-02). - (В /tmp остались чужие/ранее существовавшие
compose_new.yml,reverse-portal-compose.yml— НЕ наши, не трогали.)
- Питфолл про compose-проект: у контейнера НЕТ compose-лейблов (
- ✅ Этап 3 — рекурсивный фикс прав вглубь ВЫПОЛНЕН Alex (root) + проверен. Результат верификации 2026-09-02:
- Медиа-папки →
950:950 drwxrwx---: Cartoons, Downloads, Movies, Music, art, books, cartoons-series, documentaries(-series), series, shared, work. ✅ - Вглубь Movies: файлы →
950:950, права разблокированы (rw-r-----/rwxrwx---). ✅ - ✅ Второй root-проход ВЫПОЛНЕН Alex (вторая команда ниже) — добиты
git,nas,ada3s1,photo_dedup_test,seafile,singularity,radarr,sonarr: все теперь950:950 drwxrwx---. Проверено:- Все топ-папки storage теперь
950:950 drwxrwx---(сплошняком, кроме скрытых файлов корня и самого корня). ✅ storage/git/obsidian-vault.gitтеперь открывается —git logпоказывает коммиты (HEADa2c72793[2026-08-17]...).git/nasуже не «matching вне-списка» — chown/chmod догнаны вторым проходом.
- Все топ-папки storage теперь
- Медиа-папки →
✅ RESOLVED 2026-09-02: Блокер push снят — полной dacl-заменой, НЕ stripacl
Симптом (после починки прав): на маке git-sync теперь:
git fetch nas main → OK (bare repo доступен, fetch exit=0)
git push nas main → FAIL:
remote: fatal: loose object acd1b45542e82aa40f345da3b8ac9f721633b138 ... is corrupt
remote unpack failed: index-pack abnormal exit
sync-vault.sh — Committed потом Push failed. Ahead вырос 55 → 62 (коммиты локально копятся, не пушатся).
Диагностика — это НЕ повреждение данных, а NFS4 ACL-блокировка чтения:
| Проверка | Результат |
|---|---|
git fsck --full через root (контейнер gitea, монтирует /git-repos) |
ЧИСТО: только dangling commit/tree, ни одного corrupt/missing/bad |
git cat-file -t acd1b45... под root (gitea) |
tree — объект читается, цел |
NFS4 ACL самого файла objects/ac/d1b... (через filesystem.getacl) |
owner@ DENY READ_DATA=True поверх ALLOW → перекрывает |
Суть: у 1946 из 3373 loose git-объектов в obsidian-vault.git/objects/ стоит битый NFS4 ACL owner@ type=DENY READ_DATA=True. DENY-запись в NFSv4 перекрывает ALLOW, поэтому владелец (uid 950 = truenas_admin) не может mmap/прочитать эти объекты при push. Git на приеме (git-receive-pack/index-pack) трактует нечитаемость как «loose object corrupt» → push rejected. Root игнорирует ACL → поэтому fsck под gitea чист, а push от 950 падает. Данные целы.
POSIX-признак битых файлов: mode 40 (r--------); нормальные объекты — mode 750.
Фикс РАБОЧИЙ (RESOLVED 2026-09-02, Alex выполнил из root-шелла): ⚠️ stripacl:true с пустым dacl:[] НЕ работает — джоба при filesystem.setacl /path <json-аргументами> вываливалась Too many arguments (expected 1, found 2) (path передавался как отдельный аргумент — палево), а точечный stripacl:true на объекте дал SUCCESS, но DENY-ACL остался. Решило только полная dacl-замена (передача полного массива ACE без DENY, где owner@/group@ = ALLOW), т.е. setacl воспринимает полный dacl как .replace всего ACL, а не merge.
Проверенная рабочая команда (root-шелл для truenas_admin, job асинхронный — вернёт id, потом SUCCESS):
# точечно на один объект (проверка метода):
midclt call filesystem.setacl '{"path":"/mnt/RED_2TB/storage/git/obsidian-vault.git/objects/ac/d1b45542e82aa40f345da3b8ac9f721633b138","uid":950,"gid":950,"acltype":"NFS4","dacl":[<owner@ ALLOW полный>, <group@ ALLOW read/exec>],"options":{"recursive":false}}'
# затем рекурсивно на весь репозиторий (dacl тот же, recursive:true):
midclt call filesystem.setacl '{"path":"/mnt/RED_2TB/storage/git/obsidian-vault.git","uid":950,"gid":950,"acltype":"NFS4","dacl":[{"tag":"owner@","id":-1,"type":"ALLOW","perms":{"READ_DATA":true,"WRITE_DATA":true,"EXECUTE":false,"APPEND_DATA":true,"DELETE_CHILD":false,"DELETE":false,"READ_ATTRIBUTES":true,"WRITE_ATTRIBUTES":true,"READ_NAMED_ATTRS":true,"WRITE_NAMED_ATTRS":true,"READ_ACL":true,"WRITE_ACL":true,"WRITE_OWNER":true,"SYNCHRONIZE":true},"flags":{"BASIC":"INHERIT"}},{"tag":"group@","id":-1,"type":"ALLOW","perms":{"READ_DATA":true,"WRITE_DATA":false,"EXECUTE":true,"APPEND_DATA":false,"DELETE_CHILD":false,"DELETE":false,"READ_ATTRIBUTES":true,"WRITE_ATTRIBUTES":false,"READ_NAMED_ATTRS":true,"WRITE_NAMED_ATTRS":false,"READ_ACL":true,"WRITE_ACL":false,"WRITE_OWNER":false,"SYNCHRONIZE":true},"flags":{"BASIC":"INHERIT"}}],"options":{"recursive":true,"traverse":true}}'
Ключевое правило midclt: filesystem.setacl принимает ОДИН JSON-аргумент со всеми полями (path, uid, gid, acltype, dacl, options) — НЕ path отдельно. Job вернёт id и выполнится асинхронно; проверять midclt call core.get_jobs (state SUCCESS/error).
Проверка после (для владельца 950, НЕ root):
git --git-dir=/mnt/RED_2TB/storage/git/obsidian-vault.git cat-file -t acd1b45542e82aa40f345da3b8ac9f721633b138 # → tree
git --git-dir=/mnt/RED_2TB/storage/git/obsidian-vault.git fsck # → 0 corrupt/missing/permission denied
Результат (проверено 2026-09-02): объект читается (tree), git fsck под 950 → 0 ошибок, и с мака git push nas main прошёл (a2c7279..2b6c181 main -> main, exit=0). Локально/remote ahead=0 behind=0 — полностью синхронизировано. launchd-крона (коммиты каждые 5 мин) теперь реально пушит. Бэкап ACL репо снят до фикса: ~/variantA_bk/git_ACL_backup_2026-09-01_232328/ (root ACL + mode-map 3402 файлов).
Куда попадают DENY-ACL: артефакт restore — часть loose-объектов при переносе данных получили инверсивный NFS4 ACL (owner@ DENY read). Это НЕ родние git-права (git-репо хранит объекты как read-only r--r--r-- в обычном случае); на полке после поломки.
Диагностические insights (для будущих сессий)
docker exec transmission ...даёт root вглубь/mnt/storage(transmission монтируетstorage);giteaконтейнер монтирует/mnt/RED_2TB/storage/git → /git-reposи имеетgit— удобен дляgit fsck-честных проверок (root-контекст).hermes-taigaмонтирует/vault.git=storage/git/obsidian-vault.gitи тоже имеет git.- NFS4
owner@ DENYперекрываетALLOW— клинический кейс «ls показывает доступно, а процесс не читает». - POSIX-бит файла (mode 40/750) коррелирует с NFS4 ACL; «corrupt» от
index-packпри целых данных = почти всегда ACL/права на приеме, не реальное повреждение.
✅ Остаточный root-шаг (второй проход) — ВЫПОЛНЕН Alex; команда для справки (историческая)
Уже пройдено — итоговое состояние
950:950 drwxrwx---на всех топ-папках см. в Этапе 3 выше. Команда зафиксирована как рецепт для будущего:
S=/mnt/RED_2TB/storage
chown -R 950:950 "$S/git" "$S/nas" "$S/ada3s1" "$S/photo_dedup_test" \
"$S/seafile" "$S/singularity" "$S/radarr" "$S/sonarr" 2>/dev/null
find "$S/git" "$S/nas" "$S/ada3s1" "$S/photo_dedup_test" "$S/seafile" \
"$S/singularity" "$S/radarr" "$S/sonarr" \
-type d -exec chmod u+rwX,g+rwX,o-rwx {} + 2>/dev/null
find "$S" -maxdepth 1 -type f \( -name "._*" -o -name ".DS_Store" -o -name ".bash*" -o -name ".profile" \
-o -name ".com.apple*" \) -exec rm -f {} + 2>/dev/null
chmod -R g+rX "$S/git" 2>/dev/null
git --git-dir="$S/git/obsidian-vault.git" log --oneline -2 2>&1 | head # проверка
⚠️
rm -fскрытых файлов корня — mac-мусор/остатки старого владельца 921, безопасно. Если.profile/.bashrcрабочие — убрать их из rm по решению.
⚠️ Текущий статус после вторго прохода + RESOLUTION (актуально на 2026-09-02)
- ✅ Push на маке ПОЧИНЕН — NFS4 ACL
DENYна ~1946 loose git-объектах сняты через полную dacl-замену (не stripacl). См. секцию «✅ RESOLVED … dacl-заменой». Git-sync работает: fetch+push проходят, ahead=0 behind=0. - ✅ Arr-стек ПОДНЯТ и РАБОТАЕТ (2026-09-02). Контейнеры созданы и запущены штатно из
/mnt/RED_2TB/docker/arr:docker compose up -dв/docker/arrсоздал и запустилprowlarr,radarr,sonarr,jellyfin(все в проектеarr). Проверено: процессы работают под uid 950 (Prowlarr/Radarr/Sonarr/jellyfinpid утилиты uid=950, не root).- Сети (персистентность): для запуска потребовалось воссоздать отст.
media_net(external):docker network create media_net(она была утеряна с.ix-appsпри пересоздании пула; в compose объявлена толькоexternal: true, НЕ создаётся compose-ом → теряется при полном демонтаже docker, шаг восстановления:docker network create media_net). transmission подключён кmedia_net(для radarr/sonarr). - Пересозданный transmission compose/сети: папка
docker/transmissionстала950:950после пересоздания (была 911:911, поэтому изначально не давалаcd). Вdocker/transmission/docker-compose.ymlдобавлена networks секция:media_net+transmission_default(обе external), чтобы подключение transmission к media_net было перманентным (не живымdocker network connect). Провереноdocker compose up -dпересоздал — обе сети на месте. Порты: caddy резолвит transmission черезtransmission_default(Web UItransmission.mallexxx.duckdns.orgработает); radarr достаётtransmission:9091черезmedia_net(TR_OK). - Связка работает: jellyfin читает
/storage/Movies(READ_OK), radarr↔transmission по media_net OK (172.16.17.2:9091), все UI-порты слушают (prowlarr 9696, radarr 7878, sonarr 8989, jellyfin 8096, transmission 9091). radarr/sonarr/jellyfin монтируют/mnt/RED_2TB/storage→/storage(root folder у radarr на TrueNAS =/storage/..., не/mediaкак Kraken). - Осталось по стеку: настройка самих сервисов через их Web UI (radarr root-folder
/storage, indexers в prowlarr, библиотеки в jellyfin) — вне времени запуска; я не вмешиваюсь в конфиги.
- 🔜 Скрытые файлы корня storage (
.DS_Store,.bash_*,.profile,.com.apple*) остаются921:921 mode 0000(не добиты — в root-шаге B rm для них предлагался, но решение не подтверждено). Сам кореньstorage/→drwxrwx--- 921:921(owner 921, хотя group 950 есть). Проверить, нужен ли корню chown 950. - 🔜
books— владелец950:921(не 950:950) — оставлен как был (служебный, не критично для saga).
Точное содержание transmission compose (оригинал, важно для пересоздания)
services:
transmission:
image: lscr.io/linuxserver/transmission:latest
container_name: transmission
restart: unless-stopped
environment:
- TZ=Asia/Novosibirsk
- USER=transmission_admin
- PASS=E$%p3En4a%R6
- WHITELIST=172.16.*.*
volumes:
- /mnt/RED_2TB/storage:/mnt/storage
- /mnt/RED_2TB/docker/transmission:/config
ports:
- 9091:9091
- 51413:51413
- 51413:51413/udp
(в compose НЕ было PUID/PGID → контейнер root; transmission монтирует storage → /mnt/storage, download-dir /mnt/storage/Downloads)
6. Пост-запуск arr-стека: 2 блокера — ОБА РЕШЕНЫ (2026-09-02, конец сессии)
После успешного запуска стека (все контейнеры Up под 950) выявлены два REFAIL. Общий скрытый корень обоих + случайно та же причина, что у jellyfin-транскодинга: сам корень /mnt/RED_2TB/storage (верх датасета) остался 921:921, ACL owner@/group@ ALLOW но everyone@ EXECUTE=False → uid 950 (jellyfin/transmission как не-owner group truenas_admin...) фактически не мог traverse вглубь /storage/Movies/..., ХОТЯ ACL самих файлов/каталогов были корректными (trivial:true, owner@ READ/EXEC, 950:950). Это даёт клинический кейс «ACL файла чистый, владелец 950, но чтение = Permission denied».
✅ 6a. Jellyfin: FFmpeg exit 243 при проигрывании — РЕШЕНО
Симптом: веб-UI jellyfin (Setup завершён, StartupWizardCompleted:true) открылся, библиотеки видят /storage/Movies, но проигрывание падало FFmpeg exited with code 243 (на чтении входа /storage/Movies/Snatch.x264/..., НЕ на записи transcode — transcodes//config/cache уже стали 950 после первого chown).
Двойной корень: (1) конфиг jellyfin вглубь /config/data был 911:911 (11 441 файл; jellyfin под 950) → первый chown -R 950:950 /mnt/RED_2TB/docker/arr/jellyfin открыл UI (этот chown Alex уже выполнил ранее); (2) НО даже после него чтение файла /storage/Movies/Snatch.x264/... из uid 950 давало Permission denied при чистом ACL файла+каталога. Причина — корень /mnt/RED_2TB/storage остался 921:921 и блокировал traverse (см. выше).
Фикс ЖЕЛЕЗНО (root, Alex выполнил — заработало):
chown 950:950 /mnt/RED_2TB/storage
chmod 750 /mnt/RED_2TB/storage # rwxr-x--- → owner u950 / group(g950=truenas_admin) r-x → traverse для jellyfin
linuxserver контейнеры (jellyfin/transmission) под PUID/PGID=950 имеют gid=950 → члены
truenas_admin. После chmod 750 group r-x открывает traverse. Результат: jellyfin проигрывает (direct play / transcod по необходимости). Отключение транскодинга (если не нужен): Dashboard → Playback → снять галку «Allow media playback that requires transcoding» (тогда только Direct Play); транскодиг включается лишь когда клиент не поддерживает исходный кодек. UI наjellyfin.mallexxx.duckdns.org.
✅ 6b. Transmission: 255 торрентов "no data found" — РЕШЕНО docker restart
Симптом: transmission-UI (9091) открывался, но все 255 торрентов показывали error 3: No Data Found.
Уточнённый диагноз (проверено RPC изнутри, whitelist 172.16.*.*): downloadDir у каждого торрента УЖЕ корректно указывал не на Downloads, а на /mnt/storage/Movies (или /storage/documentaries), и файлы там физически ЕСТЬ (164 single .mkv прямо в Movies; Thursday.1998_BDRip_cw.mkv 3.1G и т.д.), владелец 950 -rw-r-----, читаются под uid 950 (docker exec -u 950 → READ_OK). НЕ проблема download-dir и НЕ права — файл доступен демону. torrent-verify поодиночке НЕ снимал ошибку.
Настоящий корень: ошибка No Data Found была закеширована при старте, когда транзит через корень /storage был ещё заблокирован (до chmod 750 на корень). transmission не перевалидировал данные после разблокировки traverse.
Фикс (НЕ root): простая перезагрузка демона заново валидирует все торренты при доступном traverse:
docker restart transmission
Результат: 254 из 255 торрентов СРАЗУ чисты (было 0). Остался только id=1 (Thursday.1998_BDRip_cw.mkv) — ранее ему крутили torrent-verify, но он всё ещё error 3; добить: в Web UI transmission на торренте → Verify Local Data, либо ещё один verify.
Вывод для будущего: «No Data Found» у всех торрентов в transmission после пересоздания/миграции данных чаще всего = старт демона при недоступном traverse к данным. Решение — починить traverse (root каталога/путь) и
docker restart. Данные при этом НЕ трогаются.
Связанные заметки
- 2026-08-31-syncthing-truenas-incident — вызвавший инцидент + фикс syncthing
- arr-stack-taiga — acquisition-стек на TrueNAS
- arr-stack-kraken — serving-стек (Kraken)
- vault-git-sync — git-sync алгоритм и скрипты
- obsidian-sync — общая схема Eagle↔Taiga↔Kraken
- syncthing-truenas-android — syncthing схема (требует обновления volumes →
obsidian-syncthing)