У меня дома стоит роутер 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
Открываем:
Transmission (Flood UI): http://localhost:9091
Jellyfin: http://localhost:8096
Как это работает внутри — три нетривиальных момента
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. Не нужно открывать лишние порты и нет сетевых задержек между контейнерами.
Команды
Команда |
Что делает |
|---|---|
|
Список всех торрентов с прогресс-барами и кнопками управления |
|
Только активные загрузки |
|
Скорости, статистика за всё время |
|
Справка |
Добавление торрентов
Три способа:
Отправить
.torrentфайл боту прямо в чатОтправить
magnet:ссылку текстомКинуть
.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 — первый запуск
Открыть http://localhost:8096
Пройти мастер настройки (язык, создать пользователя)
Добавить медиатеку → тип “Фильмы” → путь
/media/DownloadsJellyfin сам найдёт файлы, скачает постеры и описания с 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
Буду рад звёздочке ⭐ и вопросам в комментариях — особенно если столкнётесь с другими граблями на своём железе.
Комментарии (20)

LeshaRB
19.04.2026 15:45Transmission выглядит как привет из 2009 года, управлять им с телефона неудобно, а посмотреть скачанное на телевизоре — вообще отдельный квест.
На телефоне и планшете стоит Tremotesf, на роутере настроен доменное имя. Управлять удобно Что касается ТВ давал по самбе доступ к папкам на ТВ, потом докупил приставку. На приставке уже и постеры сама скачает

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

andy2000
19.04.2026 15:45Примерно тоже самое городил с полгода назад. Только телегу не прикручивал. Решил, что это излишне. Подключаюсь к домашней сетке через впн, открываю вебморду и стартую торрент.
Единственно трансмижн или реально устарел или мне так повезло. Несколько часов тестил (правда у меня он не на роутере, а на домашнем сервере) и он мне какие-то смешные скорости скачивания выдавал. Я уже начал сомневаться в самой сетке. Но в итоге его заменил на qBittorrent и все сразу полетело на максималках.

metter
19.04.2026 15:45да, встроенный имеет ограничения по скорости

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

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

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


nronnie
19.04.2026 15:45С TMDB есть еще один нюанс. Они блокируют российские IP с помощью своего DNS - можно поколдовать с /etc/hosts, но надёжней, всё-таки, ходить к ним через VPN.
Для transmission можно на любую машину поставить “Transmission Qt Client” и управлять им удалённо - нужно только открыть TCP порт 9091 (по умолчанию), ну или настроить в конфиге на свой вкус.

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

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

K0Jlya9
19.04.2026 15:45интерфейс Transmission выглядит как привет из 2009 года, управлять им с телефона неудобно
Открываю Telegram, кидаю боту
.torrentфайлОчень удобно ага, и жизненно. [/sarcasm mode off]

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

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

JellySheep
19.04.2026 15:45Затея интересная, но почему конкретно телеграм и торрент файлы? Это же не совсем удобно - можно присобачить еще контейнер с jackett, который автоматизирует поиск + загрузку, в целом его же в тг прикрутить, тогда пропадёт нужда в поиске ссылок или файлов.
И вопрос про JF - он стоит непосредственно на NAS или на пк с виндой?) По личному опыту, он может быть достаточно требовательным к карте - на что-то типа малины не поставишь, кодинг уничтожает базу сразу же, поэтому это скорее вариант для богатых с домашними серверами или готовых каждый раз дёргать компьютер.
В целом насчёт qbit/transmission+flood ui + плеер история хорошая, не хватает поисковика

vvs3 Автор
19.04.2026 15:45JF стоит на пк с виндой.
TG - чтобы жене было удобно торренты скачивать: закинул в чат с ботом и все) Здесь кому-то может показаться неудобно - нам довольно удобно.
MountainGoat
Лишь бы телеграм как-то присобачить.
binhex-qbittorrentvpn и vpn с внешним портом. Интерфейс можно в браузер зарегистрировать как обрабочик .torrent и magnet:
DerTosser
Да и просто VPN до дома, а на телефоне любое приложение-интерфейс к transmission на NAS-е и вот вам добавление торрент-файлов по клику + уведомления о завершении закачки и без докера и без телеграма.