diff --git a/package/diy/jellyfin-autoinit/Makefile b/package/diy/jellyfin-autoinit/Makefile new file mode 100644 index 0000000000..77b077e2dd --- /dev/null +++ b/package/diy/jellyfin-autoinit/Makefile @@ -0,0 +1,34 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=jellyfin-autoinit +PKG_VERSION:=1.0 +PKG_RELEASE:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/jellyfin-autoinit + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Auto-pull and start Jellyfin Docker container on first boot + PKGARCH:=all + DEPENDS:=+docker +endef + +define Package/jellyfin-autoinit/description + On first boot, after eMMC expansion is complete, this package will: + 1) docker pull jellyfin/jellyfin:2026062206-arm64 + 2) create the Jellyfin container (host network, correct webroot symlink) + 3) patch the JS startup crash bug (PR #8088) + 4) start with rkmpp hardware acceleration + + Re-runs are guarded by /etc/jellyfin-autoinit.done. +endef + +define Package/jellyfin-autoinit/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) ./files/jellyfin-autoinit.sh $(1)/usr/bin/jellyfin-autoinit.sh + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/jellyfin-autoinit.init $(1)/etc/init.d/jellyfin-autoinit +endef + +$(eval $(call BuildPackage,jellyfin-autoinit)) diff --git a/package/diy/jellyfin-autoinit/files/jellyfin-autoinit.init b/package/diy/jellyfin-autoinit/files/jellyfin-autoinit.init new file mode 100644 index 0000000000..f840efba27 --- /dev/null +++ b/package/diy/jellyfin-autoinit/files/jellyfin-autoinit.init @@ -0,0 +1,9 @@ +#!/bin/sh /etc/rc.common +# Jellyfin container auto-start on boot +# START=98 = after dockerd, before user services +# Stage ordering: dockerd → expand-overlay(99) → this(98) → user services +START=98 + +start() { + /usr/bin/jellyfin-autoinit.sh +} diff --git a/package/diy/jellyfin-autoinit/files/jellyfin-autoinit.sh b/package/diy/jellyfin-autoinit/files/jellyfin-autoinit.sh new file mode 100755 index 0000000000..0200fb1b04 --- /dev/null +++ b/package/diy/jellyfin-autoinit/files/jellyfin-autoinit.sh @@ -0,0 +1,84 @@ +#!/bin/sh +# Auto-pull and start Jellyfin Docker container on first boot +# Fixes two known bugs in jellyfin/jellyfin:2026062206-arm64: +# 1) WebRootPath points to empty /jellyfin/wwwroot/ — workaround: symlink +# 2) JS crash "item or serverId cannot be null" (PR #8088) — workaround: sed patch +# +# Gates on expand-overlay.done so it only runs after the eMMC is resized +# Idempotent: skips if container or flag file exists +# Forgiving: pull failure exits 0 so init retries next boot +# Tolerates missing expand-overlay.done (may not be created on mismatched firmware) + +FLAG_FILE="/etc/jellyfin-autoinit.done" + +# Wait up to 30s for expand-overlay to finish +for i in 1 2 3 4 5 6 7 8 9 10; do + [ -f /etc/expand-overlay.done ] && break + sleep 3 +done + +# Already done +[ -f "$FLAG_FILE" ] && exit 0 + +# Docker available? Wait for dockerd to actually be ready +if ! command -v docker >/dev/null 2>&1; then + echo "[jellyfin-autoinit] docker binary not found, exiting" + exit 0 +fi + +for i in 1 2 3 4 5 6 7 8 9 10; do + docker info >/dev/null 2>&1 && break + [ "$i" -eq 10 ] && { echo "[jellyfin-autoinit] dockerd not ready after 30s, exiting"; exit 0; } + sleep 3 +done + +# Container already exists +if docker inspect jellyfin >/dev/null 2>&1; then + echo "[jellyfin-autoinit] container already exists, skipping" + touch "$FLAG_FILE" + exit 0 +fi + +echo "[jellyfin-autoinit] pulling jellyfin/jellyfin:2026062206-arm64..." +docker pull jellyfin/jellyfin:2026062206-arm64 2>&1 | tail -3 || { + echo "[jellyfin-autoinit] pull failed, will retry next boot" + exit 0 +} + +# Ensure mount points exist +mkdir -p /mnt/usb1-0/Configs/Jellyfin/config +mkdir -p /mnt/usb1-0/Configs/Jellyfin/cache +mkdir -p /mnt/usb1-0/Caches/Jellyfin + +echo "[jellyfin-autoinit] creating container with webroot fix..." +docker run -d \ + --name jellyfin \ + --restart unless-stopped \ + --network=host \ + -e TZ=Asia/Shanghai \ + -v /mnt/usb1-0/Configs/Jellyfin:/config \ + -v /mnt/usb1-0/Caches/Jellyfin:/config/transcodes \ + -v /mnt/usb1-0:/mnt/usb1-0 \ + --entrypoint sh \ + jellyfin/jellyfin:2026062206-arm64 \ + -c 'ln -sf /jellyfin/jellyfin-web /wwwroot && exec /jellyfin/jellyfin' 2>&1 | tail -3 + +# Wait for Jellyfin API to be ready, then patch the JS startup crash bug +echo "[jellyfin-autoinit] waiting for Jellyfin to start..." +for i in 1 2 3 4 5 6 7 8 9 10 15 20; do + docker exec jellyfin curl -s http://127.0.0.1:8096/system/info/public >/dev/null 2>&1 && break + [ "$i" -eq 20 ] && { echo "[jellyfin-autoinit] Jellyfin not ready after 60s"; break; } + sleep 3 +done + +echo "[jellyfin-autoinit] patching JS startup crash bug (PR #8088)..." +docker exec jellyfin sh -c 'sed -i "s/key:\"getApi\",value:function(e){var t,n=this.getApiClient(e);return/key:\"getApi\",value:function(e){if(!e)return;var t,n=this.getApiClient(e);return/g" /wwwroot/main.jellyfin.bundle.js' + +docker restart jellyfin + +if docker ps | grep -q jellyfin; then + echo "[jellyfin-autoinit] jellyfin started successfully with all fixes applied" + touch "$FLAG_FILE" +else + echo "[jellyfin-autoinit] failed to start, will retry next boot" +fi diff --git a/r6c.config b/r6c.config new file mode 100644 index 0000000000..9fe02e4d12 --- /dev/null +++ b/r6c.config @@ -0,0 +1 @@ +CONFIG_PACKAGE_jellyfin-autoinit=y