Napi C: медиасервер (Transmission + Jellyfin / MiniDLNA)

Платформа: NAPI C, предоставлена компанией «Ниеншанц-Автоматика» / nnz-ipc.ru

Практическая попытка организовать медиасервер на этом одноплатном компьютере.


Введение — что это за плата и в каком виде пришла

Napi C — компактный одноплатный модуль на базе процессора Rockchip RK3308 (Cortex-A35, 4 ядра). Технические характеристики, кратко:

  • RK3308, 4× Cortex-A35
  • 512 МБ ОЗУ
  • 4 ГБ NAND (eMMC)
  • 1 × Ethernet 100 Мбит, 2 × USB 2.0 (Type-A и Type-C)
  • питание +5 В (GPIO или USB-C), PoE-ready
  • 3 × UART, SPI, 2 × I2C, GPIO, размер 43 × 43 мм
    (официальное описание и документация: https://napiworld.ru/docs/napi-intro
  • )

Мне прислали голый модуль — только одна плата без несущей платы, корпусов и аксессуаров. На модуле в eMMC уже стояла предустановленная ОС Armbian (вариант образа для eMMC). Задача — попробовать организовать медиасервер (Transmission + Jellyfin) и оценить, насколько это целесообразно на таком устройстве. Это не полноценный обзор или нагрузочное тестирование — это практическая попытка понять возможности платформы в роли медиасервера.


Цель и ограничения

Цель: сделать рабочий медиасервер, где Transmission будет скачивать торренты, а сервер медиа (в идеале — Jellyfin) будет проигрывать контент из той же папки. Ограничения и замечания:

  • Napi C — это скорее модуль для встраивания в проекты, а не полноценный NAS/медиасервер; RAM 512 МБ и 4 ГБ eMMC — строгие ограничения.
  • Для надёжной работы медиа-сервера лучше стабильный дистрибутив и достаточный объём постоянного хранилища (SD/HDD).
  • В процессе я сознательно добивался загрузки с SD-карты (чтобы всё стояло и хранилось на большом носителе), а не на встроенном eMMC.

Загрузка: SD vs eMMC — нюансы и проблемы

При получении модуля на eMMC был предустановлен Armbian. Я хотел, чтобы система загружалась с SD-карты (на ней — крупное хранилище, удобнее переустановки). В процессе столкнулись со следующими нюансами:

  1. Приоритет загрузки — плата по умолчанию может загружаться с eMMC, даже если вставлена SD. Часто eMMC содержит загрузчик и system image.
  2. Одинаковые UUID — при тестах выяснилось, что eMMC и SD могли иметь одинаковые UUID, что путает загрузчик и систему. Решение — корректно определить устройства и, при необходимости, поменять UUID или принудительно загрузиться с SD.
  3. Автоматическое расширение rootfs — образ, записанный на SD, часто создавался с таблицей разделов, где root-раздел был «задублирован» под размер eMMC (~3–4 ГБ). Поэтому после записи образа SD-карта физически 128/256 ГБ, но rootfs занимал лишь ≈3.4 ГБ и требовал ручного расширения.

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

  • проверка lsblk, dmesg | grep mmc, mount | grep " / " для определения, с чего загружена система;
  • если нужно — удаление загрузчика eMMC (уничтожение первых MByte) для принудительного перехода на SD (внимание: операция разрушительна для загрузчика eMMC и выполняется сознательно);
  • расширение раздела на SD: установка cloud-guest-utilsgrowpart /dev/mmcblk0 1resize2fs /dev/mmcblk0p1 (в моём случае это увеличило rootfs с ~3.4 ГБ до ~230 ГБ на 256 ГБ карте).

Замечание по безопасности: удаление/перезапись u-boot на eMMC — действие необратимое без резервной копии загрузчика и выполняется при понимании последствий. Это я сделал сознательно, чтобы быть уверенным, что система загрузится с SD.


Что с дистрибутивами (Bookworm vs Rolling)

Важно пояснить ситуацию с дистрибутивами Armbian для RK3308, потому что на этом этапе возникла путаница. На сайте Armbian для Rockpi S доступны официальные сборки:
https://www.armbian.com/rockpi-s/

По началу я запутался: официальный образ для Napi C размещён в отдельном репозитории
https://download.napilinux.ru/linuximg/armbian/armbian-napi-based-devs-rk3308bs/armbian1206/


и собирался под объём встроенной eMMC. Из-за этого некоторое время было неочевидно, откуда именно загружается система — с eMMC или с SD-карты.

Чтобы исключить неопределённость, я полностью стёр загрузчик на eMMC и после этого установил конкретный образ:

armbian-napi-rk3308bs-12062024-1.img.zip
https://download.napilinux.ru/linuximg/armbian/armbian-napi-based-devs-rk3308bs/armbian1206/armbian-napi-rk3308bs-12062024-1.img.zip

Дальнейшая работа велась именно на этом образе.

Armbian 25.8.1 Bookworm (Minimal / IoT) для Radxa Rockpi S

Сборка Armbian 25.8.1 Bookworm Minimal/IoT у меня так и не загрузилась в ожидаемом виде.

Rolling Releases (Armbian v6.12) для Radxa Rockpi S

Rolling-релиз на базе Armbian v6.12 загрузился корректно и без проблем стартовали с SD-карты. Однако у rolling-ветки есть особенности:

  • это «скользящие» сборки с максимально свежими ядрами и пакетами;
  • они часто нарушают зависимости;
  • далеко не всегда подходят для длительного стабильного использования на маломощных SBC.

Проблемы с установкой Jellyfin

При попытке установить Jellyfin на rolling-сборку появились проблемы: официальный установочный скрипт Jellyfin не поддерживает ветку plucky/rolling, а пакетные зависимости не проходили проверку.

В итоге Jellyfin был установлен через Docker — это работало, но такой подход сложно назвать оптимальным для компактного одноплатника с ограниченными ресурсами и медленным I/O.


Пространство и перенос rootfs на всю карту (шаги)

Коротко — что было сделано, чтобы SD-карта заняла весь объём:

# Установить утилиту для изменения разделов
sudo apt update
sudo apt install cloud-guest-utils -y

# Расширить первый раздел на весь диск
sudo growpart /dev/mmcblk0 1

# Расширить файловую систему ext4
sudo resize2fs /dev/mmcblk0p1

# Проверить
df -h

После этого rootfs вырос с ~3.4 GB до полного размера SD (например, 230 GB).


Transmission — установка и настройка

Transmission — лёгкий и надёжный торрент-демон, он работает без проблем на Napi C.

Шаги установки и базовой настройки:





sudo apt update
sudo apt install transmission-daemon -y

# Остановить сервис для правок
sudo systemctl stop transmission-daemon

# Откорректировать конфиг (обычно /var/lib/transmission-daemon/info/settings.json)
sudo nano /var/lib/transmission-daemon/info/settings.json
# В конфиге важно:
# "download-dir": "/srv/media/downloads",
# "incomplete-dir": "/srv/media/downloads/.incomplete",
# "incomplete-dir-enabled": true,
# "rpc-bind-address": "0.0.0.0",
# "rpc-whitelist-enabled": false,
# "rpc-authentication-required": true, "rpc-username": "...", "rpc-password": "..."

# Создать каталоги
sudo mkdir -p /srv/media/downloads
sudo chown -R debian-transmission:debian-transmission /srv/media/downloads
sudo chmod -R 775 /srv/media

После запуска Transmission через web-интерфейс (http://IP:9091) управление торрентами работало корректно. Был один ранний эпизод, когда диск eMMC был полностью заполнен — это произошло потому, что система сначала грузилась с eMMC (корень был на eMMC), и Transmission по умолчанию писал туда. После переноса и загрузки с SD проблема исчезла.


Jellyfin — попытки установки и проблемы

Я пробовал несколько путей установки Jellyfin:

  1. Прямой apt (официальный скрипт) — скрипт установки официального репозитория отказался работать с rolling (кодовое имя «plucky»).
  2. Ручное добавление репозитория (Debian bookworm) — для Bookworm это работало корректно, но в rolling возникали конфликты зависимостей (libvpx7, libicu72 и т. п.).
  3. Docker — на rolling это был самый надёжный метод: стандартный образ jellyfin/jellyfin под ARM64 запустился, и в контейнере Jellyfin видел /mnt/downloads при корректном маппинге тома (- /mnt/downloads:/media/downloads). Это сработало и позволило продолжать работу, однако Docker добавляет накладные расходы на ресурсы (RAM, IO) и сложность управления на таком ресурсо-ограниченном устройстве.

Проблемы при «системной» установке

При попытке установить Jellyfin как системный сервис (apt-пакеты) на Armbian Bookworm я столкнулся с падениями сервиса: в логах journalctl было видно UnauthorizedAccessException: Access to the path '/var/log/jellyfin' is denied. Причина — на некоторых сборках Armbian/NapiLinux /var/log смонтирован как tmpfs/zram и не позволяет Jellyfin по умолчанию создать подкаталог. Решение, которое я применил:





# Создать каталог логов и дать права
sudo mkdir -p /var/log/jellyfin
sudo chown -R jellyfin:jellyfin /var/log/jellyfin
sudo chmod 755 /var/log/jellyfin

# Или переназначить лог каталог на постоянный диск:
sudo mkdir -p /var/log.hdd/jellyfin
sudo chown jellyfin:jellyfin /var/log.hdd/jellyfin

# Создать служебный override systemd, чтобы Jellyfin использовал другой лог путь
sudo systemctl edit jellyfin
# добавить:
# [Service]
# Environment="JELLYFIN_LOG_DIR=/var/log.hdd/jellyfin"

sudo systemctl daemon-reload
sudo systemctl restart jellyfin

После таких правок Jellyfin запускался, но работа сервера оставляла желать лучшего: на RB3308 с 512 MB RAM и на небольшой системе периодически наблюдались подвисания и даже жёсткие зависания системы при длительной работе (вероятно, из-за нехватки памяти при обработке библиотеки, кешировании или попытках транскодирования). В целом Jellyfin работал, но назвать комфортным просмотр на нём я не могу — интерфейс и сканирование библиотеки было медленным, а периодические падения делали решение ненадёжным.


MiniDLNA (ReadyMedia) — простое и надёжное решение

После проблем с Jellyfin я поставил MiniDLNA (ReadyMedia) и настроил его на тот же каталог, куда качает Transmission: /srv/media/downloads. MiniDLNA — это очень лёгкий DLNA/UPnP-сервер, он не транскодирует, но отлично раздаёт готовые файлы клиентам (SmartTV, VLC и т. п.). На Napi C он работает быстро и стабильно.

Краткий порядок действий, который я сделал:





sudo apt update
sudo apt install minidlna -y

# Конфигурация (в /etc/minidlna.conf)
# media_dir=V,/srv/media/downloads
# db_dir=/var/cache/minidlna
# log_dir=/var/log/minidlna
# inotify=yes
# port=8200

sudo mkdir -p /var/cache/minidlna /var/log/minidlna
sudo chown -R minidlna:minidlna /var/cache/minidlna /var/log/minidlna
sudo chown -R minidlna:minidlna /srv/media/downloads
sudo chmod -R 755 /srv/media/downloads

sudo systemctl restart minidlna
sudo systemctl enable minidlna

MiniDLNA запустился быстро и корректно. Я проверил воспроизведение 4K-эпизода сериала «Оно. Добропожаловать в Дерри» (файл в контейнере). Сервер успешно отдавал поток в 4K на DLNA-совместимый клиент — воспроизведение шло корректно (без транскодирования).


Итоги и рекомендации

  1. Napi C — интересная компактная платформа, удобная для встроенных решений. Но для задач медиасервера её аппаратных ресурсов (512 MB RAM) и встроенного eMMC (4 GB) мало для комфортной работы современных медиа-серверов с трансляцией и транскодированием.
  2. Загрузка с SD — предпочтительна, если вы хотите большой объём места. Обязательно расширяйте rootfs до всего размера карты (growpart + resize2fs), иначе вы получите только ~3–4 GB рабочей системы.
  3. Jellyfin можно запустить, но на Napi C это «workable but uncomfortable»: для стабильной работы нужен более мощный CPU и больше RAM; на этой плате Jellyfin временами падал/зависал, были нюансы с логами и zram. На rolling-релизах удобнее ставить Jellyfin через Docker, но это добавляет нагрузку.
  4. MiniDLNA — лучший выбор для лёгкой и быстрой раздачи медиа на таких платформах: он очень лёгкий, прост в настройке, не требует больших ресурсов и прекрасно раздаёт готовые файлы. Для простого медиасервера MiniDLNA + Transmission — оптимальное соотношение «нагрузка/функции».
  5. Если нужна полноценная медиаплатформа (с веб-интерфейсом, метаданными, транс-кодированием, многопользовательским доступом) — лучше выбрать плату с минимум 2 GB RAM и более мощным CPU, либо вынести Jellyfin на Docker-хост/более мощный сервер, а Napi C использовать только как загрузчик/источник или как DLNA-сервер.

Полезные команды (сводка)

Разметка/расширение rootfs:





sudo apt update
sudo apt install cloud-guest-utils -y
sudo growpart /dev/mmcblk0 1
sudo resize2fs /dev/mmcblk0p1
df -h

Установка Transmission:





sudo apt install transmission-daemon -y
sudo systemctl stop transmission-daemon
# правка /var/lib/transmission-daemon/info/settings.json
sudo mkdir -p /srv/media/downloads
sudo chown -R debian-transmission:debian-transmission /srv/media
sudo chmod -R 775 /srv/media
sudo systemctl start transmission-daemon

Пример правок для Transmission (важно):





"download-dir": "/srv/media/downloads",
"incomplete-dir": "/srv/media/downloads/.incomplete",
"incomplete-dir-enabled": true,
"rpc-bind-address": "0.0.0.0",
"rpc-whitelist-enabled": false,
"rpc-authentication-required": true

Установка MiniDLNA:





sudo apt install minidlna -y
# отредактировать /etc/minidlna.conf:
# media_dir=V,/srv/media/downloads
# inotify=yes
# db_dir=/var/cache/minidlna
# log_dir=/var/log/minidlna
sudo mkdir -p /var/cache/minidlna /var/log/minidlna
sudo chown -R minidlna:minidlna /var/cache/minidlna /var/log/minidlna
sudo chown -R minidlna:minidlna /srv/media/downloads
sudo chmod -R 755 /srv/media/downloads
sudo systemctl restart minidlna
sudo systemctl enable minidlna

Заключение

Napi C — удобный и компактный модуль, который отлично годится для встроенных проектов и лёгких сетевых сервисов. Для роли мини-DLNA сервера в локальной сети он подходит очень хорошо: небольшие требования к ресурсам, быстрая отдача контента и простота управления. Если нужна полноценная медиаплатформа со всеми современными фичами (Jellyfin с транскодированием, пользователями, тяжелыми плагинами) — лучше рассматривать платформы с большим объёмом RAM и более мощным CPU, либо использовать Napi C в составе распределённой архитектуры (Napi C как DLNA/edge-node + отдельный сервер для Jellyfin).