MAATRIX / Блог / Tdarr на сервере: частые ошибки и решения

Tdarr на сервере: частые ошибки и решения

MAATRIX

Tdarr обещает простую вещь: скормить ему библиотеку видео и получить на выходе аккуратный HEVC вместо раздутого H.264 или разномастного зоопарка кодеков. На практике первые запуски почти всегда заканчиваются одним и тем же — нода падает через час работы, диск забивается временными файлами, а транскодер либо не видит GPU, либо использует его только для декодирования. Это стандартный набор граблей, через которые проходит почти каждый, кто разворачивает Tdarr на выделенном сервере. Ниже — разбор самых частых проблем и рабочие решения для каждой.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Нода падает или зависает при обработке больших файлов

Самая частая жалоба: Tdarr Node стабильно работает на файлах до 2-3 ГБ, а на исходниках побольше (сырые записи с камер, ремуксы 4K) просто исчезает из списка нод в вебе, либо контейнер уходит в перезапуск.

Причина почти всегда одна — нехватка оперативной памяти. FFmpeg сам по себе не требователен к RAM, но связка Tdarr + Node + плагины на крупных файлах может отъедать заметно больше, чем кажется на глаз, особенно если параллельно крутится несколько воркеров.

Проверить, что происходит на самом деле:

# смотрим потребление памяти контейнером в реальном времени
docker stats tdarr_node

# если нода падает в контейнере — смотрим последние строки лога перед смертью
docker logs --tail 200 tdarr_node

Если в dmesg находится строка вида Out of memory: Killed process с именем handbrake или ffmpeg — вопрос закрыт, это классический OOM-killer:

dmesg -T | grep -i "killed process"

Решения по приоритету:

  • Снизьте число одновременных воркеров транскодирования в настройках ноды (transcodeGpuWorkers и transcodeCpuWorkers) — для сервера с 8-16 ГБ RAM разумный старт это 1-2 воркера, а не значение по умолчанию.
  • Добавьте swap, если его нет — не решает проблему производительности, но спасает от жёсткого убийства процесса на пиковых файлах:
fallocate -l 8G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
  • Если библиотека состоит преимущественно из 4K-контента с HDR и сложными аудиодорожками — закладывайте от 16 ГБ RAM на сервер с запасом, иначе будете постоянно упираться в этот потолок.

Docker Compose с ошибками путей и прав доступа

Вторая по частоте проблема — Tdarr стартует, но не видит вашу медиатеку, либо видит, но не может писать в целевую папку. В логах — ENOENT, EACCES или папка в интерфейсе просто пустая, хотя файлы на месте.

Корень проблемы почти всегда в том, что пути внутри контейнера и снаружи не совпадают, либо владелец файлов на хосте не совпадает с UID/GID процесса внутри контейнера. Рабочий docker-compose.yml:

services:
  tdarr:
    container_name: tdarr
    image: ghcr.io/haveagitgat/tdarr:latest
    restart: unless-stopped
    network_mode: bridge
    ports:
      - "8265:8265"
      - "8266:8266"
    environment:
      - TZ=Europe/Moscow
      - PUID=1000
      - PGID=1000
      - UMASK_SET=002
      - serverIP=0.0.0.0
      - serverPort=8266
      - webUIPort=8265
      - internalNode=true
      - nodeName=internalNode
    volumes:
      - /opt/tdarr/server:/app/server
      - /opt/tdarr/configs:/app/configs
      - /opt/tdarr/logs:/app/logs
      - /mnt/media/library:/media
      - /mnt/media/transcode-cache:/temp
    devices:
      - /dev/dri:/dev/dri

Ключевые моменты, которые чаще всего упускают:

  • PUID/PGID должны совпадать с владельцем медиатеки на хосте. Узнать свои: id $(whoami). Если сервис работает от root, а файлы принадлежат обычному пользователю — получите вечные EACCES на запись.
  • Путь внутри контейнера (/media), а не хостовый /mnt/media/library, должен быть указан при добавлении Library в веб-интерфейсе. Это главная причина пустых библиотек.
  • Временную папку (/temp) обязательно выносите на отдельный volume, а не оставляйте внутри контейнера — иначе временные файлы разрастут слой контейнера до неприличных размеров и переживут даже docker system prune.

После правки прав:

chown -R 1000:1000 /mnt/media/library /mnt/media/transcode-cache /opt/tdarr
docker compose up -d

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

GPU не подхватывается: транскодирование идёт на CPU

Самая обидная ошибка — вы арендовали сервер с GPU специально ради аппаратного NVENC/QuickSync, настроили плагин, а вся нагрузка всё равно ложится на CPU: htop показывает все ядра в 100% при почти нулевой загрузке GPU в nvidia-smi.

Для NVIDIA-карт частая причина — контейнер не получил доступ к устройству. Проверка на хосте:

nvidia-smi
# если команда не находится или падает — драйвер не установлен либо сломан на хосте, дальше двигаться некуда

Проверка внутри контейнера:

docker exec -it tdarr nvidia-smi

Если внутри контейнера команда не работает, а на хосте всё в порядке — не хватает NVIDIA Container Toolkit:

# на хосте (Ubuntu/Debian)
curl -s -L https://nvidia.github.io/libnvidia-container/gpgkey | gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
  tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
apt update && apt install -y nvidia-container-toolkit
nvidia-ctk runtime configure --runtime=docker && systemctl restart docker

И добавьте в docker-compose.yml для сервиса tdarr (или tdarr_node, если ноды вынесены отдельно):

    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]

Отдельно — даже когда GPU подхватился, плагин обработки должен явно использовать флаги -hwaccel cuda -c:v hevc_nvenc (или соответствующие для вашего GPU), а не общий libx265. Проверьте вкладку Library → Transcode Options: там легко случайно оставить программный энкодер по умолчанию.

Для серверов на Intel QuickSync устройство /dev/dri должно быть проброшено в контейнер (см. пример compose выше), а пользователь внутри контейнера — состоять в группе render:

ls -l /dev/dri
usermod -aG render,video $(whoami)

Диск забивается временными файлами и логами

Через пару недель работы Tdarr на активной библиотеке сервер вдруг сообщает No space left on device, хотя медиатека вроде бы занимает разумный объём. Смотрите отдельно:

du -sh /opt/tdarr/logs
du -sh /mnt/media/transcode-cache
df -h

Частые находки:

  • Логи ноды растут бесконтрольно — по умолчанию Tdarr не всегда агрессивно их ротирует. Настройте logrotate:
cat > /etc/logrotate.d/tdarr <<'EOF'
/opt/tdarr/logs/*.log {
    daily
    rotate 7
    compress
    missingok
    notifempty
}
EOF
  • Кэш транскодирования не чистится после сбойных задач. Если процесс упал (тот же OOM из первого раздела), временный файл остаётся висеть в /temp и никогда не удаляется автоматически. Добавьте задачу в cron:
0 4 * * * find /mnt/media/transcode-cache -type f -mtime +1 -delete
  • Health check создаёт временные копии, если включена проверка целостности — на больших библиотеках это может незаметно удвоить потребление диска на время прогона. Если места мало, отключите Health Check в настройках Library или ограничьте его выборочными папками.

Под кэш транскодирования закладывайте отдельный том с запасом минимум в 2-3 раза больше среднего размера самого крупного файла в библиотеке — на 4K-исходниках это легко 40-60 ГБ на одну параллельную задачу.

Задачи зависают в очереди Queued и не двигаются

Иногда файлы подолгу лежат в статусе Queued, воркеры показывают Idle, а в логах — тишина. Чаще всего это одна из трёх причин.

Первая — плагин-стек ссылается на плагин, который был удалён или обновлён с breaking change. Проверить:

docker logs tdarr_node --tail 100 | grep -i "plugin"

Если видите ошибку загрузки — зайдите в Tdarr → Plugins и переустановите community-плагины (кнопка обновления стека), после чего пересоберите Library flow заново, а не просто нажимайте Save поверх сломанной ссылки.

Вторая причина — фильтр Library настроен так, что файл технически "не подходит" ни под одно условие в flow (например, условие ожидает контейнер .mkv, а файл — .mp4). Смотрите вкладку файла в интерфейсе — там показывается, на каком узле flow застряло решение.

Третья — нода отвалилась от сервера по сети (актуально, если Node и Server разнесены на разные машины), но интерфейс Server ещё не успел это зафиксировать. Проверка связи:

curl -s http://<server-ip>:8266/api/v2/status | jq

Если нода не отвечает — перезапустите контейнер tdarr_node и убедитесь, что serverIP в его переменных окружения указывает на реальный, доступный по сети адрес сервера, а не на 127.0.0.1 в конфиге распределённой ноды.

Perl/FFmpeg ошибки внутри плагинов на конкретных кодеках

При обработке специфичных исходников (старые DV-записи, субтитры формата PGS, многоканальный TrueHD) транскодирование падает с ошибкой FFmpeg прямо посреди задачи, а не на старте.

Первый шаг диагностики — прогнать ту же команду вручную вне Tdarr, чтобы увидеть полный вывод ffmpeg:

docker exec -it tdarr ffmpeg -i /media/problem-file.mkv -c:v hevc_nvenc -c:a copy -c:s copy /temp/test-output.mkv

Типичные находки:

  • Субтитры формата PGS/VobSub нельзя просто скопировать в контейнер, который их не поддерживает (например, при смене контейнера на MP4). Решение — либо оставлять MKV для файлов с такими субтитрами, либо явно исключать эти потоки в плагине через условие по кодеку.
  • TrueHD/DTS-HD MA с большим числом каналов иногда требует явного даунмикса, если целевой контейнер или устройство воспроизведения его не тянут — добавьте отдельный шаг в flow с -c:a eac3 -ac 6, а не полагайтесь на copy.
  • Version mismatch FFmpeg внутри образа — образы Tdarr обновляются не мгновенно, и конкретный кодек может вести себя иначе в зашитой версии. Проверить:
docker exec -it tdarr ffmpeg -version

Если баг известный и пофикшен выше по версии — обновление образа (docker compose pull && docker compose up -d) часто закрывает вопрос без танцев с конфигами.

Распределённые ноды теряют связь друг с другом

Если вы вынесли обработку на несколько серверов (основной сервер с диском под библиотеку + отдельный GPU-сервер под транскодирование), частая боль — ноды периодически отваливаются, задачи "зависают" на одном воркере, а логи говорят про таймауты соединения.

Первое — проверьте, открыты ли нужные порты между машинами в обе стороны, а не только исходящий трафик с ноды на сервер:

# на сервере Tdarr Server
ufw allow from <ip-ноды> to any port 8266 proto tcp

# проверка доступности с ноды
curl -v http://<server-ip>:8266/api/v2/status

Второе — если ноды и сервер находятся в разных сетях, задержка сама по себе не критична для Tdarr (это не realtime-протокол), но нестабильный джиттер на слабом канале может рвать долгие HTTP-соединения при передаче больших файлов. Здесь помогает разместить Server и активные Node в одном дата-центре — тогда файлы обрабатываются локально на GPU-ноде через общее хранилище NFS/SMB, а не гоняются по HTTP.

Третье — убедитесь, что nodeName уникален для каждой ноды в кластере. Дублирующиеся имена — частая причина, когда сервер путает статусы и показывает то одну, то другую ноду как offline, хотя обе живы.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Сколько RAM закладывать под сервер с Tdarr?

Для библиотеки без 4K и с 1-2 воркерами хватает 8 ГБ. Для активной обработки 4K/HDR с несколькими параллельными задачами — от 16 ГБ, плюс swap как страховка от OOM-killer.

Нужен ли обязательно GPU?

Нет, программное кодирование через libx265 работает и на CPU, но заметно медленнее и сильнее греет сервер при постоянной нагрузке. Если библиотека большая или растёт постоянно — GPU с NVENC/QuickSync окупается временем.

Почему Tdarr не видит новые файлы автоматически?

Проверьте, включён ли Folder Watch на вкладке Library, и не упирается ли путь в те же проблемы с правами, что описаны в разделе про Docker Compose.

Что делать, если после обновления образа всё перестало работать?

Посмотрите changelog релиза на breaking changes в плагинах, проверьте логи (docker logs tdarr --tail 200) и пересоздайте контейнер: docker compose up -d --force-recreate, сохранив volume с конфигами.

Можно ли гонять Tdarr на VPS без выделенного GPU?

Технически да, но для реальных объёмов видеотеки это будет медленно и упрётся в CPU. Для регулярной обработки практичнее выделенный сервер с прямым доступом к GPU.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →