Библиотека — Медиасервер: Transmission + Sonarr/Radarr + Plex [X]
Шифр
media-server-guide
Разделы
linux tooling
Сверено
2 сентября — в этот день утверждения статьи сверялись с первоисточниками, а не правился текст
Объём
27 848 знаков · 36 разделов · чтения около 30 минут

Медиасервер: Transmission + Sonarr/Radarr + Plex


Обзор

Домашний медиасервер — цепочка из четырёх компонентов: торрент-клиент (Transmission) скачивает файлы, менеджеры контента (Sonarr для сериалов, Radarr для фильмов) автоматизируют поиск, загрузку и постобработку, агрегатор индексаторов (Prowlarr) проксирует поисковые запросы к трекерам, а медиасервер (Plex) предоставляет интерфейс для просмотра с метаданными и транскодингом.

Ключевая идея архитектуры — разделение хранилища на две зоны: torrents/ (рабочая директория клиента, где файлы раздаются) и library/ (организованная библиотека для Plex с правильными именами). Связь между ними — hardlink: файл физически один на диске, но доступен по двум путям. Это работает только в пределах одной файловой системы (и одного субтома в случае Btrfs).

Архитектура

Поток данных

Prowlarr (индексаторы: rutracker, ...)
    ↓ проксирует поисковые запросы
Sonarr / Radarr (менеджеры контента)
    ↓ отправляет торрент
Transmission (загрузка)
    ↓ скачивает в /mnt/media/torrents/{series,films}/
Sonarr / Radarr (постобработка)
    ↓ создаёт hardlink с правильным именем
/mnt/media/library/{series,films}/
    ↓ сканирует
Plex (отдаёт клиентам)

Структура каталогов

/mnt/media/                        # точка монтирования (Btrfs)
├── torrents/                      # Transmission: рабочая директория
│   ├── films/                     # категория Radarr
│   ├── series/                    # категория Sonarr
│   ├── books/                     # ручные загрузки
│   ├── music/                     # ручные загрузки
│   └── .incomplete/               # незавершённые загрузки
├── library/                       # Plex: библиотека (hardlink)
│   ├── films/                     # Plex тип "Фильмы"
│   └── series/                    # Plex тип "Телепередачи"
├── books/                         # хранилище книг (вне Plex)
└── .torrent-files/                # бэкап .torrent файлов

Hardlink — второе имя для тех же данных на диске (тот же inode). В отличие от symlink, hardlink неотличим от «оригинала» — оба пути равноправны. Удаление одного не затрагивает другой; данные исчезают только когда удалены все ссылки на inode.

Ограничения: hardlink работает только внутри одной файловой системы и одного субтома Btrfs. Поэтому torrents/ и library/ должны находиться на одном субтоме. Книги и .torrent-files/ можно вынести в отдельные субтома (они не нуждаются в hardlink) и снапшотить независимо.

Проверить, что файл — hardlink, а не копия:

stat file.mkv | grep Links   # Links: 2 означает hardlink
ls -li file1 file2           # одинаковый inode = один файл

Права на чтение мало — нужна запись

Ядро по умолчанию работает с fs.protected_hardlinks=1. При такой настройке жёсткую ссылку на файл разрешено создавать только если вызывающий им владеет либо имеет права на чтение и запись. Одного чтения не хватает.

Отсюда типичный сценарий: Transmission кладёт файл как wes:wes 664, Radarr работает в группе media, к чужому файлу у него остаются права r--, и link() возвращает EPERM. В логе это выглядит так:

Debug|DiskProvider|Hardlink '/mnt/media/torrents/films/X.mkv' to
                   '/mnt/media/library/films/X (2024)/X (2024).mkv' failed.
   at NzbDrone.Mono.Disk.DiskProvider.TryCreateHardLink(...)

Соответственно, лечится не правами на каталог, а группой и битом setgid (см. раздел о правах доступа).

На Btrfs поломка не видна по свободному месту

Когда жёсткая ссылка не удалась, *Arr молча копирует файл. На Btrfs File.Copy в .NET идёт через copy_file_range(), а ядро превращает это в reflink — CoW-клон, у которого свой inode, но общие экстенты с оригиналом. Место при этом не тратится, и обычная проверка «сколько занято» ничего не покажет.

Ловушка в том, что du, вызванный по каждому каталогу отдельно, посчитает такие данные дважды:

$ du -sh /mnt/media/library /mnt/media/torrents
758G  /mnt/media/library
730G  /mnt/media/torrents      # сумма 1.5 ТБ...

$ df -h /mnt/media
/dev/nvme0n1p1  932G  780G  152G  84%  /mnt/media   # ...а занято 778 ГБ

Расхождение почти ровно вдвое — признак, что данные разделены, но неизвестно чем: жёсткими ссылками или reflink. Различать их надо по числу ссылок и по экстентам:

# сколько файлов реально связаны жёстко (Links > 1)
find /mnt/media/library -type f -size +100M -printf '%n\n' | sort -n | uniq -c

# делят ли два конкретных файла одни экстенты
filefrag -v "library/films/X (2024)/X (2024).mkv" "torrents/films/X.mkv"
# одинаковый physical_offset и флаг shared = reflink

Практическая разница: reflink расходится при первой же перезаписи любой из копий, а на файловой системе без CoW (ext4, XFS) того же места просто не хватило бы. То есть на Btrfs сломанные hardlink маскируются, но чинить их всё равно надо.

Права доступа

Все сервисы должны работать с общей группой media, чтобы файлы, созданные одним сервисом, были доступны другим:

sudo groupadd -f media
sudo usermod -aG media wes
sudo usermod -aG media sonarr
sudo usermod -aG media radarr
sudo usermod -aG media plex

Systemd-юниты Sonarr и Radarr должны содержать Group=media. Transmission (user-level unit) наследует группы пользователя wes. Umask 002 для всех сервисов обеспечивает права 775/664 — группа media может читать и писать.

sudo chgrp -R media /mnt/media
sudo chmod -R 775 /mnt/media

После изменения групп обязательно перезапустить все сервисы, иначе новая группа не подхватится.

Бит setgid обязателен, иначе всё разъедется обратно

Одного chgrp -R недостаточно: он чинит только те файлы, что есть сейчас. Новые файлы получают основную группу процесса-создателя, а не группу каталога. Transmission работает под wes, чья основная группа — wes, поэтому каждая свежая загрузка ложится как wes:wes, и группа media доступа к ней не имеет.

Лечится битом setgid на каталогах — с ним новые файлы наследуют группу каталога:

sudo find /mnt/media -type d -exec chmod g+s {} +

Проверка — в выводе ls -ld должна стоять s вместо x в правах группы:

$ ls -ld /mnt/media/torrents
drwxrwsr-x 1 wes media 170 /mnt/media/torrents
       ↑ setgid на месте

Быстрый тест наследования:

touch /mnt/media/torrents/films/.test && \
  stat -c '%U:%G' /mnt/media/torrents/films/.test && \
  rm /mnt/media/torrents/films/.test
# должно напечатать wes:media, а не wes:wes

Альтернатива — прописать media основной группой Transmission (Group=media в юните или usermod -g), но setgid надёжнее: он работает и для файлов, положенных руками.

Установка (CachyOS / Arch)

Компоненты

# Transmission daemon (если не установлен)
sudo pacman -S transmission-cli

# Sonarr, Radarr, Prowlarr — бинарные пакеты из AUR
paru -S sonarr-bin radarr-bin prowlarr-bin

# Plex
paru -S plex-media-server

Запуск сервисов

Transmission на CachyOS может работать как user-level systemd unit:

# проверить
systemctl --user status transmission
systemctl --user enable --now transmission.service

# НЕ использовать одновременно системный юнит — будут конфликты:
sudo systemctl disable --now transmission-daemon

Остальные сервисы — системные:

sudo systemctl enable --now sonarr radarr prowlarr plexmediaserver

Веб-интерфейсы:

Сервис URL
Transmission http://localhost:9091
Sonarr http://localhost:8989
Radarr http://localhost:7878
Prowlarr http://localhost:9696
Plex http://localhost:32400/web

Настройка Transmission

Конфиг: ~/.config/transmission-daemon/settings.json

Критически важно: daemon перезаписывает settings.json при остановке. Редактировать только при остановленном сервисе:

systemctl --user stop transmission.service
# ... редактирование ...
systemctl --user start transmission.service

Ключевые параметры:

{
    "download-dir": "/mnt/media/torrents",
    "incomplete-dir": "/mnt/media/torrents/.incomplete",
    "incomplete-dir-enabled": true,
    "watch-dir": "/mnt/media/.torrent-files",
    "watch-dir-enabled": true,
    "umask": "002",
    "cache-size-mb": 16,
    "encryption": 2,
    "rpc-bind-address": "127.0.0.1",
    "rpc-authentication-required": false
}

watch-dir — бросаешь .torrent файл в эту папку, Transmission подхватывает автоматически. Файл не удаляется (trash-original-torrent-files: false), остаётся как бэкап.

umask: "002" — файлы создаются с правами 664/775, доступны группе media.

encryption: 2 — требовать шифрование (отсекает часть пиров, но снижает вероятность инспекции трафика).

Управление через CLI

# список торрентов
transmission-remote -l

# добавить торрент в конкретную категорию
transmission-remote --add file.torrent --download-dir /mnt/media/torrents/films
transmission-remote --add "magnet:?xt=..." --download-dir /mnt/media/torrents/series

# инфо по торренту
transmission-remote -t 1 -i

# переместить файлы торрента (раздача продолжится из нового места)
transmission-remote -t 1 --move /mnt/media/torrents/books

# удалить торрент (файлы остаются)
transmission-remote -t 1 -r

# удалить торрент и файлы
transmission-remote -t 1 -rad

Настройка Prowlarr

Prowlarr — единый агрегатор индексаторов. Настраивается первым, потому что Sonarr и Radarr к нему подключаются.

  1. http://localhost:9696 → настроить аутентификацию (Forms, Disabled for Local Addresses)
  2. Indexers → Add Indexer → найти rutracker.org → указать логин/пароль
  3. Settings → Apps → добавить Sonarr (URL: http://localhost:8989, API Key из Sonarr → Settings → General)
  4. Settings → Apps → добавить Radarr (URL: http://localhost:7878, API Key из Radarr → Settings → General)
  5. На главной → Sync App Indexers — принудительный проброс индексаторов

После этого rutracker автоматически появится в Sonarr и Radarr как индексатор.

Настройка Sonarr (сериалы)

Download Client

Settings → Download Clients → «+» → Transmission:

  • Host: localhost, Port: 9091
  • Username/Password: пусто (если rpc-authentication-required: false)
  • Category: series — Transmission создаст подкаталог /mnt/media/torrents/series
  • Remove Completed: выключить, если хочешь продолжать раздавать

Media Management

Settings → Media Management:

  • Rename Episodes: включить — Sonarr будет переименовывать файлы при импорте
  • Root Folders → Add: /mnt/media/library/series

Профили качества

Settings → Profiles → выбрать/создать профиль (например HD-1080p). Здесь настраивается: какие форматы качества приемлемы, разрешён ли автоматический upgrade, и язык (в Sonarr v4 через Custom Formats).

Настройка Radarr (фильмы)

Аналогично Sonarr:

  • Download Client: Transmission, Category: films
  • Media Management: Rename Movies — включить, Root Folder: /mnt/media/library/films

Настройка Plex

http://localhost:32400/web → мастер настройки.

Библиотеки:

  • Тип «Фильмы» → путь /mnt/media/library/films
  • Тип «Телепередачи» (TV Shows) → путь /mnt/media/library/series

Plex работает от пользователя plex. Убедиться, что он в группе media и имеет доступ на чтение к /mnt/media/library/.

Одна оговорка про сам выбор Plex, появившаяся уже после того, как эта схема была собрана. С 30 апреля 2025 года воспроизведение личной медиатеки вне домашней сети перестало быть бесплатным: нужен либо Plex Pass у владельца сервера, либо Remote Watch Pass у того, кто смотрит. Ограничение включали не сразу — принудительное применение началось в конце ноября 2025 с Roku и в 2026 расползлось на Fire TV, Android TV, Apple TV и сторонние клиенты. Локального просмотра это не касается вовсе, так что описанная здесь схема работает как работала, но если сервер нужен и снаружи, выбор сужается до подписки или до Jellyfin, у которого удалённый доступ ничем не ограничен.

Naming convention для Plex

Plex опирается на имена папок и файлов для скрапинга метаданных:

Фильмы:   /library/films/Movie Name (Year)/Movie Name (Year).ext
Сериалы:  /library/series/Show Name/Season XX/Show Name - SxxExx - Episode Title.ext

Sonarr и Radarr создают hardlink с правильными именами автоматически при импорте — вручную переименовывать не нужно.

Рабочие процессы

Автоматический путь (Sonarr/Radarr находят раздачу)

  1. Sonarr/Radarr → Add New → найти сериал/фильм
  2. Указать Root Folder, профиль качества, что мониторить
  3. Включить «Start search for missing» или запустить поиск вручную
  4. Sonarr/Radarr найдёт раздачу через Prowlarr → отправит в Transmission
  5. После скачивания — автоматический hardlink в library/ с правильным именем
  6. Plex подхватит при сканировании

Для ручного выбора конкретной раздачи (озвучка, качество): Interactive Search — иконка с человечком (не обычная лупа, которая хватает первую подходящую).

Ручной путь (раздача не находится автоматически)

  1. Добавить сериал/фильм в Sonarr/Radarr без автопоиска
  2. Скачать .torrent с rutracker
  3. Добавить в Transmission с указанием категории:
transmission-remote --add file.torrent --download-dir /mnt/media/torrents/series
# или /mnt/media/torrents/films для фильмов
  1. Дождаться завершения загрузки
  2. В Sonarr/Radarr: Wanted → Manual Import → указать путь к скачанным файлам → Interactive Import
  3. Сопоставить файлы с эпизодами/фильмом (Series, Season, Episode)
  4. Убедиться что внизу стоит Hardlink/Copy Files (не Move)
  5. Import — hardlink создаётся в library/
  6. Plex подхватит при сканировании

Управление раздачами

После импорта торрент остаётся в Transmission и продолжает раздаваться из torrents/. В Sonarr Queue он может висеть как «не импортированный» — в этом случае: Queue → выбрать → Remove → Ignore Downloads (не Remove from Download Client, чтобы не удалить файлы и не прервать раздачу).

Когда раздача больше не нужна:

transmission-remote -t ID -r     # удалить торрент, файлы остаются
transmission-remote -t ID -rad   # удалить торрент и файлы из torrents/

При удалении файлов из torrents/ — hardlink в library/ продолжает жить (данные не удаляются, пока существует хотя бы одна ссылка на inode). И наоборот.

Книги и прочий контент вне Plex

Книги не проходят через Sonarr/Radarr. Простой путь:

transmission-remote --add file.torrent --download-dir /mnt/media/torrents/books

Или переместить уже скачанный торрент:

transmission-remote -t ID --move /mnt/media/torrents/books

Нюансы и подводные камни

Cloudflare на трекере: FlareSolverr

RuTracker закрывает /forum/login.php управляемым челленджем Cloudflare. Prowlarr исполнять JavaScript не умеет и получает 403 с телом «Just a moment…», после чего уводит индексер в нарастающий бэкофф:

Warn|IndexerHttpClient|HTTP Error - Res: HTTP/2.0 [POST]
     https://rutracker.org/forum/login.php: 403.Forbidden
Warn|RuTracker|RuTracker.org HTTP request failed: [403:Forbidden]
     at NzbDrone.Core.Indexers.Definitions.RuTracker.DoLogin()

Характерная деталь: index.php при этом отдаёт нормальные 200. Челлендж висит именно на логине, поэтому «сайт открывается» — плохой тест. Проверять надо конкретный эндпоинт:

curl -s -o /dev/null -w '%{http_code}\n' https://rutracker.org/forum/index.php  # 200
curl -s -o /dev/null -w '%{http_code}\n' https://rutracker.org/forum/login.php  # 403

Ни User-Agent браузера, ни куки с главной страницы не помогают — челлендж настоящий, его надо исполнять. Решает FlareSolverr: он держит настоящий Chromium под виртуальным дисплеем, проходит проверку и отдаёт куку cf_clearance.

Headless не проходит, Xvfb проходит

Ключевой момент: Cloudflare детектит headless-режим. Проверить, решаем ли челлендж с конкретного IP, можно и без FlareSolverr — запустив обычный Chromium под Xvfb и посмотрев, появилась ли кука:

xvfb-run -a --server-args='-screen 0 1920x1080x24' \
    chromium --no-sandbox --user-data-dir=/tmp/chprof \
    https://rutracker.org/forum/login.php &
sleep 60; pkill -f 'user-data-dir=/tmp/chprof'

sqlite3 /tmp/chprof/Default/Cookies 'select host_key, name from cookies'
# наличие cf_clearance = челлендж решается, дело не в репутации IP

Если куки нет — проблема в самом адресе (репутация датацентрового IP), и FlareSolverr не спасёт.

Ставить сборку из исходников, не -bin

В AUR два пакета. flaresolverr-bin несёт внутри собственный Chrome, собранный под старую NSS; с актуальной системной nss проверка сертификатов уходит в бесконечную рекурсию и рендерер падает:

ERROR  Error solving the challenge. Message: invalid session id:
       session deleted as the browser has closed the connection

В coredumpctl при этом видно TrustStoreNSS::GetTrust → TrustStoreCollection::GetTrust дважды подряд по одному адресу.

Пакет flaresolverr (из исходников) использует системный chromium и системный chromedriver. Версии в Arch выходят одним пакетом и всегда совпадают, NSS одна на всех — конфликт исчезает:

paru -Rns flaresolverr-bin
paru -S flaresolverr
sudo systemctl enable --now flaresolverr

journalctl -u flaresolverr | grep -E 'Chromium|Test'
#   Chrome / Chromium path: /usr/bin/chromium
#   Chrome / Chromium major version: 151
#   Test successful!

Подключение к Prowlarr

FlareSolverr добавляется как Indexer Proxy и действует только на индексеры с тем же тегом:

  1. Settings → Indexers → Indexer Proxies → + → FlareSolverr, Host http://localhost:8191/, тег flaresolverr.
  2. Тот же тег повесить на сам индексер (Indexers → RuTracker → Tags).

Без тега прокси не применится, и симптом не изменится. После настройки первый запрос занимает 20–30 секунд (решается челлендж), последующие — доли секунды, пока живёт сессия.

FlareSolverr по умолчанию слушает 0.0.0.0:8191. Это прокси, скачивающий по запросу произвольный URL, поэтому наружу его лучше не выставлять:

# /etc/systemd/system/flaresolverr.service.d/bind-localhost.conf
[Service]
Environment="HOST=127.0.0.1"

Теги Prowlarr: синхронизация в приложения

У поля Tags в Prowlarr два независимых смысла, и это легко перепутать:

Где стоит тег Что делает
Indexer Proxy + индексер запросы к этому индексеру идут через прокси
Application (Sonarr/Radarr) + индексер только помеченные индексеры уезжают в это приложение

Второе — способ держать индексер в Prowlarr, но не отдавать его в *Arr. Полезно, когда определение трекера плохо раскладывает результаты по категориям: например, RuTor отдаёт всё как 8000/Other, из-за чего Radarr либо отказывается сохранять индексер («Query successful, but no results in the configured categories»), либо принимает его и потом впустую опрашивает.

Важный побочный эффект: как только у Application появился хоть один тег, непомеченные индексеры перестают синхронизироваться. Новый индексер без тега молча не доедет до Sonarr и Radarr.

Ещё одна особенность: при syncLevel = fullSync Prowlarr перезаписывает настройки индексера в приложении. Руками поправленные категории живут до ближайшей синхронизации, потом откатываются.

Сервисы должны переживать выход из сессии и ждать диск

Три ошибки уровня systemd, каждая проявляется не сразу.

Transmission как user-сервис умирает вместе с сессией. Sonarr и Radarr — системные и работают всегда, поэтому после разлогина они ломятся в мёртвый RPC:

Warn|DownloadMonitoringService|Unable to retrieve queue and history items from Transmission

Лечится не переездом в системные юниты (это перенос данных и риск для раздач), а одной командой — она разрешает менеджеру systemd --user стартовать при загрузке и жить без сессии:

loginctl enable-linger $USER   # пароль не нужен, polkit разрешает для себя

Никто не ждёт /mnt/media. Если раздел не смонтировался, Plex пометит библиотеку недоступной, а *Arr увидят пустую корневую папку. Для системных юнитов:

# /etc/systemd/system/<сервис>.service.d/media-mount.conf
[Unit]
RequiresMountsFor=/mnt/media

Для пользовательских это не работает — менеджер systemd --user не видит системные mount-юниты. Там нужен цикл ожидания в ExecStartPre:

[Service]
ExecStartPre=/home/wes/bin/wait-mount.sh /mnt/media 60

VPN стартует позже индексеров. Если трекер доступен только через туннель, а openvpn-client@… поднимается вручную или просто медленнее, Prowlarr успевает сделать несколько неудачных запросов и уводит индексер в бэкофф. Порядок задаётся через After= плюс ожидание маршрута; скрипт ожидания должен возвращать 0 в любом случае, иначе сервис не стартует вовсе при выключенном VPN.

[Unit]
After=openvpn-client@deu.service

[Service]
ExecStartPre=/usr/local/bin/wait-vpn.sh 45
TimeoutStartSec=90

TimeoutStartSec здесь не украшение. Он отсчитывается на весь старт целиком, включая ExecStartPre, и если окажется меньше лимита ожидания — systemd убьёт скрипт раньше, чем тот успеет сдаться. Юнит навсегда залипает в activating (start-pre), а Restart=on-failure превращает это в бесконечный цикл:

prowlarr.service: start-pre operation timed out. Terminating.
prowlarr.service: Failed with result 'timeout'.
prowlarr.service: Scheduled restart job, restart counter is at 9.

Значение по умолчанию задаётся DefaultTimeoutStartSec и не универсально: в CachyOS это 15 секунд вместо привычных 90. Проверять надо у себя — systemctl show -p DefaultTimeoutStartUSec.

Вторая, более коварная половина проблемы: ExecStartPre исполняется внутри песочницы юнита. Пакеты *Arr приезжают с агрессивным хардненингом, и среди прочего там есть SystemCallFilter=~@privileged вместе с SystemCallErrorNumber=EPERM. iproute2 на старте вызывает drop_cap() — сбрасывает свои capabilities через cap_set_proc(), то есть через capset(), а этот вызов входит в @privileged. Фильтр возвращает EPERM, и ip уходит в exit(EXIT_FAILURE) прямо там: код 1, пустой вывод, ни строчки в stderr — при живом туннеле. Проверка вида ip route show 0.0.0.0/1 | grep -q tun0 не срабатывает никогда, и скрипт честно ждёт весь лимит.

Отдельно стоит запомнить, почему это так тяжело поймать руками: drop_cap() выполняется только при uid != 0 && euid != 0. Под root та же команда в той же песочнице отработает нормально, и проверка «а если запустить вручную» ничего не покажет — воспроизводится только под учёткой сервиса.

Диагностируется воспроизведением песочницы в user-менеджере, по одной опции за раз:

systemd-run --user -q --pipe --wait \
  -p SystemCallFilter=@system-service -p SystemCallFilter=~@privileged \
  -p SystemCallErrorNumber=EPERM \
  ip route show 0.0.0.0/1
# rc=1, вывод пуст; без ~@privileged — rc=0 и маршрут на месте

Лечится отказом от внешних утилит в пользу /proc/net/route: чтение файла не требует ни одного привилегированного вызова и работает в любой песочнице. Адрес и маска записаны шестнадцатерично в порядке little-endian, поэтому 0.0.0.0/1 — это Destination=00000000 и Mask=00000080:

#!/bin/sh
# Ждёт маршрут через tun0, максимум N секунд. Код возврата всегда 0.
limit=${1:-45}
n=0
while [ "$n" -lt "$limit" ]; do
    if awk '$1=="tun0" && $2=="00000000" && $8=="00000080" {found=1}
            END {exit !found}' /proc/net/route 2>/dev/null; then
        exit 0
    fi
    n=$((n + 1))
    sleep 1
done
exit 0

Обобщение шире одного скрипта: в ExecStartPre захардненного юнита нельзя рассчитывать на ip, iptables и прочие утилиты, работающие с capabilities. Либо читать /proc и /sys напрямую, либо выносить команду из песочницы префиксом + в ExecStartPre=.

Тишина вместо уведомлений

По умолчанию в Sonarr, Radarr и Prowlarr не настроено ни одного Connection, а health-статус виден только в веб-морде. Отказ единственного индексера в такой конфигурации может тянуться неделями — формально всё «работает», просто ничего не находится.

Минимум, который стоит поднять сразу: любой Connection на события Health Issue и Health Restored, либо внешний опрос /api/v3/health:

curl -s -H "X-Api-Key: $KEY" http://localhost:8989/api/v3/health

Ответ [] — всё чисто. Иначе список объектов с полями type (warning / error) и message.

Transmission daemon и конфиг

Transmission перезаписывает settings.json при остановке. Если редактировать при работающем daemon — изменения затрутся при рестарте. Всегда: stop → edit → start.

На CachyOS может быть два экземпляра: user-level (systemctl --user) и system-level (sudo systemctl). Они конфликтуют за RPC-порт. Использовать только один, второй отключить.

Sonarr и нестандартные имена файлов

Sonarr сопоставляет файлы с эпизодами по имени. Если раздача названа нестандартно (номер без префикса S01E, русское название, нумерация через точку), автоматический импорт может не сработать — Sonarr интерпретирует 01. как номер сезона, а не эпизода.

Решение: Manual Import → Interactive Import → вручную указать Series, Season, Episode для каждого файла.

Выбор озвучки

Sonarr/Radarr выбирают раздачу по критериям качества и размера, не различая озвучки. Для контроля:

  • Interactive Search (иконка с человечком) — показывает все найденные раздачи, по названию видна озвучка
  • Custom Formats — создать формат с условием «Release Title contains: Кураж-Бамбей» (или другой перевод), назначить положительный score в профиле качества

Для русскоязычного контента с rutracker Manual/Interactive Search часто надёжнее полной автоматики.

Аниме

При добавлении аниме-сериала в Sonarr: Series Type → Anime (вместо Standard). Это меняет логику нумерации на абсолютную и формат поисковых запросов. Дополнительно можно добавить аниме-индексаторы (Nyaa, AniDex) в Prowlarr.

Hardlink не работает между разными субтомами Btrfs. torrents/ и library/ должны быть в одном субтоме. books/ и .torrent-files/ можно вынести в отдельные субтома для независимого снапшотирования.

Для медиафайлов (уже сжатые кодеки H.264/H.265) — compress=zstd на уровне субтома бесполезен, только тратит CPU. Для книг и .torrent-файлов сжатие полезно.

Источники


Связанные заметки

Из библиотеки института уносят только знания. Читателей здесь не считают: посещение не регистрируется, отметок в издании не остаётся, счётчиков нет ни у одного издания фонда.

Издание пополняется и пересверяется. Текст доступен на условиях CC BY-SA 4.0 — унесённое можно передавать дальше на тех же условиях.