У меня дома стоит роутер Keenetic с USB-диском на 2 ТБ. Долгое время он работал просто как сетевое хранилище — файлы лежат, Transmission на роутере крутится, всё вроде бы работает. Но дефолтный интерфейс Transmission выглядит как привет из 2009 года, управлять им с телефона неудобно, а посмотреть скачанное на телевизоре — вообще отдельный квест.

Однажды вечером решил это исправить. Итог — три Docker-контейнера, которые поднимаются одной командой, и теперь выглядит это так:

  • Открываю Telegram, кидаю боту .torrent файл

  • Бот подтверждает: “✅ Добавлен!”

  • Через время пишет: “✅ Скачано! ? Название фильма · ? 15 ГБ”

  • Открываю Jellyfin на телевизоре — фильм уже там, с постером и описанием на русском

Расскажу как это всё устроено.

Что получится в итоге

  • Transmission + Flood UI — торрент-клиент с современным интерфейсом вместо дефолтного

  • Jellyfin — медиасервер с постерами, описаниями, субтитрами. Работает на телевизоре, телефоне, в браузере

  • Telegram-бот — добавляй торренты и получай уведомления прямо в мессенджере

  • Watch-папка — кинул .torrent файл в папку на NAS, качается само

  • Всё хранится на сетевом диске NAS (SMB/CIFS) и переживёт переустановку ОС

Стек и архитектура

┌─────────────────────────────────────┐
│           Docker на Windows         │
│                                     │
│  ┌──────────────┐ ┌──────────────┐  │
│  │ Transmission │ │   Jellyfin   │  │
│  │  + Flood UI  │ │   :8096      │  │
│  │  :9091       │ └──────┬───────┘  │
│  └──────┬───────┘        │          │
│         │     ┌──────────┘          │
│  ┌──────┴─────┴──┐                  │
│  │  Docker Volume │                 │
│  │  (CIFS/SMB)    │                 │
│  └──────┬────────┘                  │
│  ┌──────┴───────┐                   │
│  │ Telegram Bot │                   │
│  └──────────────┘                   │
└─────────────┬───────────────────────┘
              │ SMB
┌─────────────▼───────────────────────┐
│         NAS / Keenetic              │
│   \\192.168.1.хх\Transmission       │
│   ├── Downloads/   ← фильмы         │
│   ├── .incomplete/ ← в процессе     │
│   └── watch/       ← auto-add       │
└─────────────────────────────────────┘

Ключевая идея — Docker volume типа CIFS монтирует сетевую шару напрямую внутрь контейнеров. Оба контейнера (Transmission и Jellyfin) работают с одними и теми же файлами на NAS: первый пишет, второй читает.

Требования

  • Docker Desktop (Windows / macOS) или Docker Engine (Linux)

  • NAS или роутер с USB-диском и SMB-шарой (Keenetic, Synology, QNAP и др.)

  • Telegram-аккаунт для бота

Нет NAS? В конце есть FAQ с вариантом на локальной папке.

Шаг 1. Клонируем репозиторий

git clone https://github.com/vervs3/mediabox.git
cd mediabox

Структура проекта:

mediabox/
├── docker-compose.yml
├── .env.example
├── bot/
│   ├── bot.py
│   ├── Dockerfile
│   └── requirements.txt
└── transmission/
    ├── setup-flood.sh
    └── custom-cont-init.d/
        └── 01-fix-settings.sh

Шаг 2. Настраиваем конфигурацию

cp .env.example .env

Редактируем .env:

# Часовой пояс
TZ=Europe/Moscow

# Сетевой диск (NAS, роутер Keenetic и т.д.)
SMB_HOST=//192.168.1.45/Transmission
SMB_USER=admin
SMB_PASSWORD=your_password

# Telegram-бот (получить у @BotFather)
BOT_TOKEN=123456789:AAxxxxx...

# Ваш Telegram ID (получить у @userinfobot)
ALLOWED_USER_ID=123456789

Шаг 3. Устанавливаем Flood UI

Здесь первые грабли. Я ожидал что образ linuxserver/transmission включает Flood прямо из коробки — раньше так и было. Но в свежих версиях сторонние UI убрали, и при запуске контейнер пишет:

Changes Required!
This image no longer bundles 3rd party Transmission UI packages.
We would advise you to use subfolders under /config to store your UI packages

Поэтому скачиваем Flood вручную:

# Linux / macOS
bash transmission/setup-flood.sh

Скрипт скачивает последний релиз flood-for-transmission и распаковывает в transmission/config/flood-ui/.

На Windows — скачайте архив вручную с GitHub releases и распакуйте в папку transmission/config/flood-ui/.

Шаг 4. Запускаем

docker compose up -d

При первом запуске Docker скачает образы (~700 МБ суммарно) и запустит все три сервиса.

Проверяем:

docker compose ps
NAME               STATUS
transmission       Up
jellyfin           Up
transmission-bot   Up

Открываем:

Как это работает внутри — три нетривиальных момента

1. Docker volume с CIFS вместо bind mount

Первое что я попробовал — пробросить сетевой диск Z:\ как обычный volume:

volumes:
  - "Z:/:/downloads"  # Не работает!

Не работает. Docker Desktop на Windows работает поверх WSL2, и смонтированные в Windows сетевые диски (Z:\, \\server\share) недоступны изнутри контейнера. WSL2 просто их не видит.

Решение — Docker volume с драйвером CIFS. Docker сам монтирует шару напрямую, минуя Windows:

volumes:
  downloads:
    driver: local
    driver_opts:
      type: cifs
      device: ${SMB_HOST}
      o: "username=${SMB_USER},password=${SMB_PASSWORD},vers=3.0,uid=1000,gid=1000,file_mode=0777,dir_mode=0777"

Оба контейнера — Transmission и Jellyfin — подключают этот volume и работают с одними файлами. Transmission пишет в /downloads/Downloads, Jellyfin читает из /media/Downloads (это один и тот же volume, просто под разными именами внутри контейнеров).

2. Патч настроек Transmission при каждом старте

Второй сюрприз — образ linuxserver/transmission при каждом запуске перезаписывает часть настроек дефолтными значениями. Пытаешься задать watch-dir через переменные окружения — не применяется. Правишь settings.json — при следующем старте снова сбрасывается.

Помогает механизм custom-cont-init.d: скрипты из этой папки выполняются после инициализации образа, но до старта transmission-daemon. Подкладываем туда патч:

#!/bin/sh
# Создаём нужные папки на шаре
mkdir -p /downloads/Downloads
mkdir -p /downloads/.incomplete
mkdir -p /downloads/watch

# Патчим settings.json
SETTINGS=/config/settings.json
if [ -f "$SETTINGS" ]; then
    sed -i 's|"watch-dir": ".*"|"watch-dir": "/downloads/watch"|' $SETTINGS
    sed -i 's|"watch-dir-enabled": false|"watch-dir-enabled": true|' $SETTINGS
    sed -i 's|"download-dir": ".*"|"download-dir": "/downloads/Downloads"|' $SETTINGS
    sed -i 's|"incomplete-dir": ".*"|"incomplete-dir": "/downloads/.incomplete"|' $SETTINGS
    sed -i 's|"incomplete-dir-enabled": false|"incomplete-dir-enabled": true|' $SETTINGS
fi

В логах видно что скрипт выполнился:

[custom-init] Files found, executing
[custom-init] 01-fix-settings.sh: executing...
[custom-init] 01-fix-settings.sh: exited 0
Connection to localhost (127.0.0.1) 9091 port [tcp/*] succeeded!

3. Git Bash ломает пути в переменных окружения

Третий подводный камень специфичен для Windows + Git Bash. Когда передаёшь путь вида /flood-for-transmission/ через -e в docker run, Git Bash радостно превращает его в C:/Program Files/Git/flood-for-transmission/.

В логах это выглядит так:

ERR utils.cc:144 Couldn't read 'C:/Program Files/Git/flood-for-transmission//index.html'

Лечится переменной окружения перед командой:

MSYS_NO_PATHCONV=1 docker run ...

В docker-compose.yml эта проблема не возникает — там пути не проходят через интерпретатор Git Bash.

Telegram-бот

Бот работает в контейнере с network_mode: "service:transmission" — разделяет сетевой стек с Transmission и подключается к нему через localhost:9091. Не нужно открывать лишние порты и нет сетевых задержек между контейнерами.

Команды

Команда

Что делает

/list

Список всех торрентов с прогресс-барами и кнопками управления

/active

Только активные загрузки

/stats

Скорости, статистика за всё время

/help

Справка

Добавление торрентов

Три способа:

  1. Отправить .torrent файл боту прямо в чат

  2. Отправить magnet: ссылку текстом

  3. Кинуть .torrent в папку watch на NAS — Transmission подхватит сам

Прогресс-бар из юникода

Мелочь, но приятная — прогресс отображается прямо в тексте сообщения:

def progress_bar(pct, width=12):
    filled = round(pct * width)
    return "█" * filled + "░" * (width - filled)

# [████████░░░░] 67%

Уведомления о завершении без дублей

Чтобы бот не спамил уже завершёнными торрентами при рестарте, при старте инициализируем множество уже скачанных ID:

async def check_completed(app):
    # При старте — молча запоминаем уже завершённые
    torrents = await client.get_torrents(["id", "percentDone"])
    completed_ids = {t["id"] for t in torrents if t["percentDone"] == 1.0}

    while True:
        await asyncio.sleep(CHECK_INTERVAL)
        torrents = await client.get_torrents(["id", "name", "percentDone", "totalSize"])
        for t in torrents:
            if t["percentDone"] == 1.0 and t["id"] not in completed_ids:
                completed_ids.add(t["id"])
                # Только новые завершения — уведомляем
                await notify_completed(app, t)

Когда торрент скачается, бот пришлёт:

✅ Скачано!

? Название.Фильма.2025.WEB-DL.1080p
? 15.2 ГБ

[? Подробнее]  [? Удалить]

Jellyfin — первый запуск

  1. Открыть http://localhost:8096

  2. Пройти мастер настройки (язык, создать пользователя)

  3. Добавить медиатеку → тип “Фильмы” → путь /media/Downloads

  4. Jellyfin сам найдёт файлы, скачает постеры и описания с TMDB

Подключение с телевизора или телефона

Установите приложение Jellyfin (Android TV, Apple TV, Roku, Fire TV, iOS, Android) и введите:

http://192.168.x.x:8096

Где 192.168.x.x — локальный IP вашего компьютера (ipconfig на Windows, ip a на Linux).

FAQ

Q: Работает ли без NAS, просто на локальной папке?

Да. Замените volume в docker-compose.yml:

volumes:
  downloads:
    driver: local
    driver_opts:
      type: none
      device: /absolute/path/to/folder
      o: bind

Q: Как добавить VPN чтобы провайдер не видел торренты?

Добавьте сервис gluetun и переведите Transmission на его сеть:

transmission:
  network_mode: "service:gluetun"
  depends_on:
    - gluetun

Q: Как обновить до новых версий образов?

docker compose pull && docker compose up -d

Q: Можно ли открыть доступ извне, не только в локальной сети?

Да, проще всего через Tailscale или Cloudflare Tunnel — без проброса портов на роутере.

Итог

Стек получился компактным — три контейнера, один docker-compose.yml, один .env файл с паролями. Поднимается с нуля за 5 минут, файлы живут на NAS и никуда не денутся при переустановке ОС.

Если у вас дома лежит роутер с USB-диском и вы до сих пор смотрите кино через проводник — попробуйте. Разница ощутимая.

Репозиторий: https://github.com/vervs3/mediabox

Буду рад звёздочке ⭐ и вопросам в комментариях — особенно если столкнётесь с другими граблями на своём железе.

Комментарии (21)


  1. MountainGoat
    19.04.2026 15:45

    Лишь бы телеграм как-то присобачить.

    binhex-qbittorrentvpn и vpn с внешним портом. Интерфейс можно в браузер зарегистрировать как обрабочик .torrent и magnet:


    1. DerTosser
      19.04.2026 15:45

      Да и просто VPN до дома, а на телефоне любое приложение-интерфейс к transmission на NAS-е и вот вам добавление торрент-файлов по клику + уведомления о завершении закачки и без докера и без телеграма.


  1. LeshaRB
    19.04.2026 15:45

    Transmission выглядит как привет из 2009 года, управлять им с телефона неудобно, а посмотреть скачанное на телевизоре — вообще отдельный квест.

    На телефоне и планшете стоит Tremotesf, на роутере настроен доменное имя. Управлять удобно Что касается ТВ давал по самбе доступ к папкам на ТВ, потом докупил приставку. На приставке уже и постеры сама скачает


  1. ash_lm
    19.04.2026 15:45

    .


  1. LakeOfTears
    19.04.2026 15:45

    ну такое... для комфорта не хватает Sonarr, Radarr, Jellyseerr


  1. endoftime
    19.04.2026 15:45

    Вот интересно, сколько качал торрента, ну никогда по именованию файла постер нормально не касается. Что угодно, но не реальный фильм. И городить такое для просмотра фильмов, ну так себе...учитывая что тележка нормально не особо работает....


  1. andy2000
    19.04.2026 15:45

    Примерно тоже самое городил с полгода назад. Только телегу не прикручивал. Решил, что это излишне. Подключаюсь к домашней сетке через впн, открываю вебморду и стартую торрент.

    Единственно трансмижн или реально устарел или мне так повезло. Несколько часов тестил (правда у меня он не на роутере, а на домашнем сервере) и он мне какие-то смешные скорости скачивания выдавал. Я уже начал сомневаться в самой сетке. Но в итоге его заменил на qBittorrent и все сразу полетело на максималках.


    1. metter
      19.04.2026 15:45

      1. andy2000
        19.04.2026 15:45

        Возможно, но у меня не встроенный. На домашнем сервере крутится proxmox и для торрент клиента я выделил отдельный lxc контейнер. Куда накатывал, естественно, не какую-то урезанную версию, а что ни на есть полную. Даже, для прикола, накручивал контейнеру кучу ресурсов, но один фиг скорость скачивания не превышала 2Мб, при канале 500.

        Возможно и можно его докрутить, но простая замена клиента, почти на дефолтных настройках, решила проблему и качает на полный канал (ну на сколько позволил)))


  1. Alexinthecold
    19.04.2026 15:45

    Saltbox

    Попробуйте. Готовый нетфликс стек


  1. v-milenin
    19.04.2026 15:45

    У меня домашний сервер с transmission (выдает полную скорость как по тарифу), файлы на скачивание отправляю из браузера с помощью transmission easy client. Смотрю на андроид тв, приложение nova video player - постеры само качает (большинство правильно), описание, картинки


  1. Incognito4pda
    19.04.2026 15:45

    Нууу... без карточки с описанием и обложкой к фильму, оповещение в телеге о загрузке торрента, прямо скажем не канон:


  1. nronnie
    19.04.2026 15:45

    С TMDB есть еще один нюанс. Они блокируют российские IP с помощью своего DNS - можно поколдовать с /etc/hosts, но надёжней, всё-таки, ходить к ним через VPN.

    Для transmission можно на любую машину поставить “Transmission Qt Client” и управлять им удалённо - нужно только открыть TCP порт 9091 (по умолчанию), ну или настроить в конфиге на свой вкус.


    1. Celir
      19.04.2026 15:45

      Ага, они используют геоднс и отдают 127.0.0.1 на запросы из рф. Через впн надёжнее, но я вопрос решал и через установку quad9 в качестве dns.


  1. VenbergV
    19.04.2026 15:45

    1) Как все уже сказали, через раз, надо вручную распознание фильма делать. Иначе будете очень удивлены названиям и обложкам.
    2) Запускать torrent через свой выстраданый vpn?! Можно нарваться на блокировку со стороны vds/vps. А вот распознавание метаданных Jellyfin неплохо бы и через vpn пропускать. Т.к. TMDB заблокировал нас.
    3) Jellyfin без поддержки аппаратного транскодинга?! На телевизоре, или клиентском устройстве может не оказаться нужного декодера. (А аппаратный транскодинг вообще возможен на WSL2?)


  1. K0Jlya9
    19.04.2026 15:45

    интерфейс Transmission выглядит как привет из 2009 года, управлять им с телефона неудобно

    Открываю Telegram, кидаю боту .torrent файл

    Очень удобно ага, и жизненно. [/sarcasm mode off]


  1. Zerpico
    19.04.2026 15:45

    Под "Домашний Netflix" мне кажется куда более удобнее и проще будет Lampa.mx (на телеке/планшете/компе/телефоне) + TorrServe (на сервер)


  1. LLIYTHUK
    19.04.2026 15:45

    Чем лампа + торрсерв не устроили? Смотри торрента онлайн и не надо ничего качать заранее.


  1. JellySheep
    19.04.2026 15:45

    Затея интересная, но почему конкретно телеграм и торрент файлы? Это же не совсем удобно - можно присобачить еще контейнер с jackett, который автоматизирует поиск + загрузку, в целом его же в тг прикрутить, тогда пропадёт нужда в поиске ссылок или файлов.

    И вопрос про JF - он стоит непосредственно на NAS или на пк с виндой?) По личному опыту, он может быть достаточно требовательным к карте - на что-то типа малины не поставишь, кодинг уничтожает базу сразу же, поэтому это скорее вариант для богатых с домашними серверами или готовых каждый раз дёргать компьютер.

    В целом насчёт qbit/transmission+flood ui + плеер история хорошая, не хватает поисковика


    1. vvs3 Автор
      19.04.2026 15:45

      JF стоит на пк с виндой.

      TG - чтобы жене было удобно торренты скачивать: закинул в чат с ботом и все) Здесь кому-то может показаться неудобно - нам довольно удобно.


  1. nbaranov
    19.04.2026 15:45

    На андроид ТВ ставим lampa она уже имеет каталог фильмов с постерами и описаниями.

    Добавляете в неё какой-нибудь jacred сервер для поиска торрентов.

    Рядом ставите matrix и подключаем его к лампе.

    Всё, лампа сама в реалтайие качает торренты через матрикс и показывает вам в телевизор. Без НАСы, ЮСБи, СМС и регистрации.