Мой сетап домашнего медиа сервера

от автора

С чего всё началось

С момента как появился домашний сервер было желание сделать нормальный медиа сервер — чтобы по красоте смотреть фильмы и сериалы в 4K, без костылей.

Начиналось всё просто: сам искал фильм на rutracker, закидывал в qBittorrent, а папка загрузок была расшарена с клиентом. Клиентом сначала был Kodi — не устроил ни вид, ни функционал. Поставил Plex — уже приятнее, но часть функций платная, что крайне не устраивало.

В итоге перешёл на Jellyfin и он мне понравился. Но проблема осталась та же: часть метаданных и обложек не подгружалась, а самому всё равно приходилось искать фильм и вручную кидать его в qBittorrent, выбирая категорию указывающую куда положить файл.

Хотелось, чтобы в одном приложении искал фильм, нажимал «скачать» — и дальше само: разложилось на фильмы и сериалы, подтянулись метаданные, обложки, всё как положено.

Цель

Свести получение любого фильма или сериала к одному действию: нашёл → нажал «скачать» → посмотрел. Всё остальное — поиск релиза, скачивание, проверка качества и языка дорожки, переименование файла, раскладка по нужным папкам библиотеки — должно происходить где-то фоново, без меня. Отдельно не хотелось терять качество выбора. Раньше при ручном поиске я сам сравнивал раздачи по качеству, сидам, дорожкам.

Что получилось на выходе

Ключевой результат — из Jellyfin теперь вообще не нужно выходить. Плагин Jellyfin-Enhanced встраивает поиск и запрос через Seerr прямо в интерфейс Jellyfin: ищу фильм, жму «скачать» — не переключаясь на отдельную вкладку или приложение. А дальше система сама находит релиз на трекере, проверяет его по метаданным, скачивает, переименовывает и кладёт в правильную папку. Через некоторое время фильм уже находится в библиотеке Jellyfin с обложкой и описанием, готовый к просмотру. Ну просто песня, то, что и хотел.

Пример карточки

Пример карточки

Отступление

Готового решения «поставил — и работает» под такой результат я не нашёл. Когда собирал всю эту связку, мягко говоря не был в восторге от того, сколько отдельных инструментов пришлось ставить на каждый чих. Radarr отвечает только за фильмы, Sonarr — только за сериалы, Prowlarr — только за подключение к торрент-трекерам, Seerr — за поиск поверх всего перечисленного. Чтож так сложно жить-то, почему до сих пор никто не собрал это всё в один готовый контейнер — вопрос открытый.

Архитектура

Jellyfin — единственная точка входа глазами пользователя. Через плагин Jellyfin-Enhanced — поиск и запрос (проксируется в Seerr), плюс просмотр готовых файлов из /movies и /tv. Seerr — поиск (TMDB) и маршрутизации запроса — кому передать, Radarr или Sonarr — и проверки, что уже есть в библиотеке. Интерфейс к нему теперь встроен в Jellyfin через плагин, отдельно как вкладку не открываю.
Radarr — весь жизненный цикл фильма: запрос → поиск релиза через индексер → скачивание → сверка по метаданным → переименование → hardlink в /movies. Следит за апгрейдом качества.
Sonarr — то же самое для сериалов, плюс отслеживание выхода новых серий по сезонам (нумерация S01E05, докачка пропущенного).
Prowlarr — держит подключение к индексеру (например к rutracker) и раздаёт его в Radarr и Sonarr одной настройкой.
qBittorrent — просто качает файл в папку своей категории.

docker-compose.yaml
networks:  home-network:    driver: bridge    external: trueservices:  qbittorrent:    image: lscr.io/linuxserver/qbittorrent:latest    container_name: qbittorrent    restart: unless-stopped    ports:      - "8080:8080"    environment:      - PUID=1000      - PGID=1000      - WEBUI_PORT=8080    volumes:      - /etc/localtime:/etc/localtime:ro      - ./qbittorrent/config:/config      - /mnt/media:/data    networks:      - home-network  radarr:    image: lscr.io/linuxserver/radarr:latest    container_name: radarr    restart: unless-stopped    ports:      - "7878:7878"    environment:      - PUID=1000      - PGID=1000      - TZ=Europe/Moscow    volumes:      - /etc/localtime:/etc/localtime:ro      - ./radarr/config:/config      - /mnt/media:/data    networks:      - home-network  sonarr:    image: lscr.io/linuxserver/sonarr:latest    container_name: sonarr    restart: unless-stopped    ports:      - "8989:8989"    environment:      - PUID=1000      - PGID=1000      - TZ=Europe/Moscow    volumes:      - /etc/localtime:/etc/localtime:ro      - ./sonarr/config:/config      - /mnt/media:/data    networks:      - home-network  prowlarr:    image: lscr.io/linuxserver/prowlarr:latest    container_name: prowlarr    restart: unless-stopped    ports:      - "9696:9696"    environment:      - PUID=1000      - PGID=1000      - TZ=Europe/Moscow    volumes:      - /etc/localtime:/etc/localtime:ro      - ./prowlarr/config:/config    networks:      - home-network  seerr:    image: ghcr.io/seerr-team/seerr:latest    init: true    container_name: seerr    restart: unless-stopped    ports:      - "5055:5055"    environment:      - TZ=Europe/Moscow      - LOG_LEVEL=info    volumes:      - /etc/localtime:/etc/localtime:ro      - ./jellyseerr/config:/app/config    networks:      - home-network  jellyfin:    image: jellyfin/jellyfin:latest    container_name: jellyfin    volumes:      - ./jellyfin/config:/config      - ./jellyfin/cache:/cache      - /mnt/media/movies:/movies      - /mnt/media/tv:/tv    restart: unless-stopped    network_mode: host    environment:      - JELLYFIN_PublishedServerUrl=http://192.168.0.2:8096    devices:      - /dev/dri:/dev/dri

В ходе экспериментов возможно что-то уже упустил или забыл убрать из docker-compose.yaml, но это текущий мой рабочий конфиг.

Из ключевого там это единый путь /data во всех контейнерах. qbittorrent, radarr и sonarr монтируют /mnt/media под одним и тем же путём. Это обязательное условие для того, чтобы Radarr/Sonarr переносили готовый файл через hardlink, а не через полное копирование — мгновенно и без расхода места на диске дважды.

Настройка Radarr

1) Settings → Media Management → Root Folders → /data/movies

2) Settings → Media Management → Importing → Use Hardlinks instead of Copy

3) Settings → Download Clients → Add → qBittorrent: Host: qbittorrent (имя контейнера — оба в одной сети home-network, резолвится по имени), Port: 8080 , Username/Password: логин-пароль от WebUI, Category: radarr
4) Settings → Connect → Jellyfin (URL http://jellyfin:8096 + API-ключ) — чтобы библиотека обновлялась сразу после импорта.

Настройка Sonarr

То же самое: Root Folder /data/tv, категория sonarr, Use Hardlinks, Connect → Jellyfin.

Настройка Prowlarr

1) Indexers → Add Indexer → RuTracker.org → логин/пароль от аккаунта.

2) Settings → Apps → Add Application:

Radarr: Prowlarr Server http://prowlarr:9696, Radarr Server http://radarr:7878, API Key из Radarr, Sync Level: Full Sync

Sonarr: аналогично, http://sonarr:8989После этого rutracker сам появляется в индексерах у Radarr и Sonarr — прописывать его там второй раз не нужно.

Настройка Seerr

1) Settings → Services → Jellyfin (URL, логин), Radarr (URL + API Key), Sonarr (URL + API Key)

2) Settings → General → регион/язык ru-RU — тайтлы и описания на русском (данные из TMDB)

3) Раз сервер личный — включил автоодобрение заявок: Request сразу уходит в работу, без второго подтверждения

Настройка Jellyfin

Чтобы вся связка заработала как нужно, необходимо поставить плагин Jellyfin-Enhanced. Инструкция по установке простая, просто в Jellyfin добавляем репозиторий, устанавливаем плагин и перезагружаем сервис. После этого в настройках в меню у нас появится пункт «Jellyfin Enhanced.

Переходим в данный раздел, открываем Seerr и настраиваем по инструкции.

На этом настройка закончена. Перезагружаем Jellyfin, обновляем страницу, пишем поиске название и нажимаем «Запрос» (скачать) и все.

Грабли по пути

В Seerr ничего не загружалось, страницы фильмов и сериалов, в Jellyfin не подтягивались метаданные. Спустя время была найдена причина — не было доступа до themoviedb. У меня стоит AdGuard поэтому я там в настройках DNS, в Upstream DNS servers переопределил днс добавив пару строк которые и решили проблему:

[/themoviedb.org/]9.9.9.9   [/tmdb.org/]9.9.9.9

Плагины которые поставил

jellyfin-editors-choice-plugin — Полноразмерный слайдер на главной странице с подборкой контента, как на Netflix. Источник подборки — избранное конкретного пользователя или случайная выборка с фильтром по рейтингу.

Jellyfin-Enhanced — помимо интеграции с Seerr это также популярный UX-плагин: горячие клавиши, кастомизация субтитров, кастомизация карточки фильма, отзывы с TMDB.

intro-skipper — по аудио-отпечатку определяет заставку/титры и даёт кнопку «Пропустить» как в Netflix. Работает по всей библиотеке автоматически, разового сканирования достаточно.

jellyfin-icon-metadata — заменяет текстовые ссылки на источники метаданных (IMDb, TMDb, TheTVDB и т.д.) на иконки на странице фильма/сериала.

Будущие цели

Вроде бы получил все что хотел, но порой хочется просто выбрать какой-то рандомный фильм, а не конкретный. В Seerr для этого есть раздел фильмы/сериалы/найти что-то новое с подборками по рекомендациям, студиям и тд. Вот этого не хватаетв в Jellyfin для полной автономности. Есть плагин SeerrFin но там пока что только просто лента фильмов/сериалов, без возможности искать рекомендации, по жанрам, студиям.

ссылка на оригинал статьи https://habr.com/ru/articles/1063160/