SSD Nodes Learn Hosting plans →
راهنماها Matt Connorتوسط Matt Connor · به‌روزرسانی شده 2026-08-26

راه‌اندازی Jellyfin روی VPS: آموزش کامل نصب با Docker

با استفاده از Docker و یک فایل compose، سرور Jellyfin خود را روی VPS اجرا کنید. این راهنما مشکلات مجوز فایل و چالش‌های transcoding در سرورهای بدون GPU را بررسی می‌کند.

آنچه در حال ساخت آن هستید

یک سرور رسانه‌ای Jellyfin روی یک VPS: شامل یک کانتینر، سه volume و یک دیسک block-storage برای نگهداری فیلم‌ها و سریال‌های شما که از هر مرورگر یا اپلیکیشن Jellyfin قابل دسترسی است. نصب این سرویس با یک فایل compose پانزده‌خطی انجام می‌شود. هر مشکلی که پس از آن رخ دهد، ناشی از دو مورد است: مجوزهای دسترسی فایل که کانتینر قادر به خواندن آن‌ها نیست، و درخواست از یک VPS بدون GPU برای transcoding ویدیو که توانایی انجام آن را ندارد. این راهنما بخش عمده‌ای از حجم خود را به این دو مورد اختصاص داده است، زیرا اکثر درخواست‌های پشتیبانی مربوط به همین مسائل هستند.

نرم‌افزار Jellyfin رایگان و کاملاً متن‌باز است؛ بدون نیاز به حساب کاربری، بدون قابلیت‌های پولی و بدون تله‌متری. به همین دلیل است که نام آن در تقریباً تمام فهرست‌های مواردی که ارزش self-hosting در سال 2026 را دارند دیده می‌شود. این نرم‌افزار رسانه‌هایی که مالک آن‌ها هستید را پخش می‌کند. Jellyfin هیچ محتوایی ارائه نمی‌دهد و این راهنما نیز درباره نحوه تهیه محتوا نیست.

واقعیت transcoding، پیش از اجاره هر چیزی

این بخش را ابتدا بخوانید، زیرا تصمیمات خرید شما را تغییر می‌دهد. یک مدیا سرور هنگام فشردن دکمه پخش، یکی از دو کار زیر را انجام می‌دهد. Direct play فایل را همان‌طور که هست استریم می‌کند: VPS بایت‌ها را از دیسک می‌خواند و روی شبکه می‌فرستد که تقریباً هیچ فشاری به CPU وارد نمی‌کند. Transcoding ویدیو را در لحظه دوباره کدگذاری می‌کند؛ رزولوشن جدید، کدک جدید یا چسباندن زیرنویس به تصویر، همگی کارهای سنگین برای CPU هستند.

یک VPS معمولی فاقد GPU است. بنابراین هر عملیات transcode روی CPU و با استفاده از libx264/libx265 انجام می‌شود و کدگذاری نرم‌افزاری بسیار هزینه‌بر است. یک transcode ساده 1080p با کدک H.264 می‌تواند چندین vCPU اشتراکی را کاملاً درگیر کند؛ transcode برای 4K یا HEVC معمولاً نمی‌تواند با سرعت پخش زنده همگام شود، در نتیجه پخش متوقف شده و مدام با بافرینگ مواجه می‌شوید. قابلیت Hardware transcoding که در سیستم‌های خانگی با Intel iGPU یا کارت‌های Nvidia این کار را ارزان می‌کند، در VPS در دسترس نیست مگر اینکه ارائه‌دهنده شما instanceهای مجهز به GPU اجاره دهد.

بنابراین استراتژی کلی در VPS این است: از transcoding اجتناب کنید. کتابخانه خود را با کدک‌هایی نگه دارید که کلاینت‌های شما به‌صورت بومی (natively) پخش می‌کنند؛ ویدیوی H.264، صدای AAC یا AC3 در کانتینر MP4 یا MKV. از اپلیکیشن‌های کلاینتی استفاده کنید که از قابلیت direct-play پشتیبانی می‌کنند: اپلیکیشن‌های بومی Jellyfin برای Android TV، iOS و Roku، به‌علاوه Infuse، Kodi و Jellyfin Media Player دسکتاپ. اگر این کار را انجام دهید، VPS هرگز با ffmpeg درگیر نمی‌شود و یک سرور متوسط با 2 vCPU می‌تواند همزمان برای چندین نفر استریم کند. اگر قصد استفاده از transcoding دارید، به یک سرور بسیار بزرگ‌تر و گران‌تر نیاز خواهید داشت و حتی در آن صورت هم 4K گزینه مطمئنی نیست.

محاسبهٔ پهنای باند را نیز انجام دهید، چون این بخش غافل‌گیری دیگری ایجاد می‌کند. در direct play، فایل با bitrate خود ارسال می‌شود. یک فایل فشردهٔ 1080p معمولاً به 8-12 Mbps نیاز دارد؛ remux بلوری 1080p به 20-30 Mbps و 4K HDR به 40-80 Mbps. اگر 3 نفر فایل‌های 10 Mbps را به‌صورت direct play تماشا کنند، 30 Mbps آپلود پایدار از VPS شما مصرف می‌شود. در پلن خود 2 عدد را بررسی کنید: سرعت پورت، یعنی آیا می‌تواند 30 Mbps ترافیک upstream را ارسال کند، و سقف انتقال ماهانه. یک فیلم 2 ساعته با bitrate برابر 10 Mbps، حدود 9 GB ترافیک خروجی ایجاد می‌کند. بنابراین سهمیهٔ اندازه‌گیری‌شدهٔ 1 TB در ماه، کمی بیشتر از 100 فیلم در ماه را پوشش می‌دهد؛ یعنی 3 یا 4 فیلم در روز. تماشای 4K در یک household، به‌دلیل bitrate چهار تا هشت برابر بیشتر، این سهمیه را بسیار سریع‌تر مصرف می‌کند. هر ترافیک خروجی دیگری را که از همان سرور ارسال می‌شود نیز از همین بودجه کم کنید؛ از جمله یک relay خودمیزبان RustDesk که هر زمان 2 peer نتوانند مستقیماً به هم متصل شوند، کل session دسکتاپ راه دور را منتقل می‌کند.

پیش‌نیازها

  • یک سرور مجازی Ubuntu 24.04 KVM تازه با دسترسی root یا sudo، به همراه Docker و افزونه Compose نصب‌شده.
  • یک فضای ذخیره‌سازی Block Storage برای رسانه‌ها، با ظرفیت متناسب با کتابخانه شما (به بخش تعیین اندازه در ادامه مراجعه کنید). دیسک روت کوچکی که همراه VPS ارائه می‌شود، محل مناسبی برای ذخیره فیلم‌ها نیست.
  • یک نام دامنه اگر قصد دسترسی عمومی HTTPS دارید، یا یک WireGuard VPN روی همان VPS اگر ترجیح می‌دهید کل سیستم خصوصی باقی بماند.
  • رسانه‌هایی که از نظر قانونی مجاز به استریم آن‌ها هستید؛ شامل فایل‌های ریپ‌شده توسط خودتان، ضبط‌های شخصی یا فایل‌هایی که مالکیت آن‌ها را دارید.

ابتدا block storage را mount کنید

volume را در پنل ارائه‌دهندهٔ خود متصل کنید، سپس آن را پیدا کرده و mount کنید. نام دستگاه را از طریق lsblk به دست آورید؛ این نام چیزی شبیه به /dev/sdb یا /dev/vdb خواهد بود و هرگز نباید دیسک root باشد.

lsblk
sudo mkfs.ext4 /dev/sdb          # ONLY on a new, empty volume — this ERASES it
sudo mkdir -p /mnt/media
sudo blkid /dev/sdb              # copy the UUID shown for this device

آن را با استفاده از UUID و نه /dev/sdb mount کنید، زیرا حروف شناسایی دستگاه‌ها پس از هر بار reboot تغییر می‌کنند و ممکن است در نهایت دیسک اشتباهی را فرمت یا mount کنید. یک خط به /etc/fstab اضافه کنید:

UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx  /mnt/media  ext4  defaults,nofail  0  2
sudo mount -a
df -h /mnt/media

nofail اهمیت دارد: بدون آن، اگر block volume در هر زمانی جدا شود، سرور از بوت شدن خودداری کرده و به یک emergency shell می‌رود. بزرگ‌ترین اشتباه در اینجا اجرای mkfs.ext4 روی volumeای است که از قبل حاوی داده است، زیرا باعث پاک شدن آن می‌شود. فقط volumeهای جدید را فرمت کنید؛ اگر دیسک از قبل حاوی کتابخانهٔ شماست، مستقیماً به سراغ خط fstab بروید.

چیدمان رسانه‌ها مطابق با انتظار Jellyfin

Jellyfin متاداده‌ها را بر اساس نام پوشه‌ها و فایل‌ها تطبیق می‌دهد. اگر چیدمان نادرست باشد، فیلم‌ها به صورت فایل‌های بدون عنوان و بدون پوستر نمایش داده می‌شوند یا یک قسمت سریال با سریالی اشتباه تطبیق می‌یابد. دقیقاً سه قانون وجود دارد: هر فیلم باید در پوشه اختصاصی خود با نام Name (Year) و نام فایل منطبق قرار گیرد؛ پوشه‌های فصل باید با نام Season 01 باشند، نه S01؛ فایل‌های قسمت سریال از الگوی S01E01 استفاده می‌کنند و قسمت‌های ویژه (Specials) در Season 00 قرار می‌گیرند.

/mnt/media
├── Movies
│   ├── Blade Runner (1982)
│   │   └── Blade Runner (1982).mkv
│   └── Arrival (2016)
│       └── Arrival (2016).mkv
└── Shows
    └── Severance (2022)
        ├── Season 01
        │   ├── Severance - S01E01.mkv
        │   └── Severance - S01E02.mkv
        └── Season 00
            └── Severance - The Lexington Letter.mkv

عبارت (Year) در نام فیلم‌ها صرفاً جنبه تزئینی ندارد، بلکه بازسازی‌ها (remakes) را متمایز می‌کند تا موتور تطبیق، عنوان صحیح را پیدا کند. پوشه‌های Movies و Shows را به عنوان پوشه‌های سطح بالای مجزا نگه دارید، زیرا هر کدام به یک کتابخانه Jellyfin با نوع محتوای خاص تبدیل می‌شوند و ترکیب آن‌ها باعث سردرگمی ارائه‌دهنده متاداده خواهد شد. Jellyfin می‌تواند یک پوشه سوم برای عکس‌ها را نیز ایندکس کند، اما تجربه کاربری آن در مقایسه با یک سرور اختصاصی عکس بسیار محدود است؛ بنابراین اگر آلبوم‌های شما اهمیت دارند، آن‌ها را در سرور جداگانه‌ای با PhotoPrism یا Immich میزبانی کنید و این سرور را فقط به فیلم و سریال اختصاص دهید.

مجوزها: دلیل اصلی خالی ماندن کتابخانه‌ها

این یک تصور غلط است که باعث هدر رفتن وقت بسیاری از کاربران می‌شود. ایمیج رسمی jellyfin/jellyfin از متغیرهای محیطی PUID/PGID پشتیبانی نمی‌کند؛ این متغیرها متعلق به ایمیج LinuxServer.io (lscr.io/linuxserver/jellyfin) هستند. در ایمیج رسمی، شما کاربر را با کلید user: در فایل compose کنترل می‌کنید و اگر آن را حذف کنید، کانتینر با دسترسی root اجرا می‌شود. از هر کدام که استفاده کنید، قانون یکسان است: uid/gid که کانتینر با آن اجرا می‌شود، باید بتواند تمام دایرکتوری‌های رسانه را بخواند و در آن‌ها پیمایش کند.

ما با uid/gid 1000 اجرا می‌کنیم که اولین کاربر غیر root در یک سیستم Ubuntu استاندارد است. مقدار خود را تایید کرده و مالکیت را تنظیم کنید:

id                                  # confirm your user is uid=1000 gid=1000
sudo chown -R 1000:1000 /mnt/media
sudo find /mnt/media -type d -exec chmod 755 {} \;
sudo find /mnt/media -type f -exec chmod 644 {} \;
mkdir -p ~/jellyfin/config ~/jellyfin/cache
sudo chown -R 1000:1000 ~/jellyfin

دایرکتوری‌ها علاوه بر دسترسی خواندن، به بیت execute (همان x در 755) نیاز دارند. بدون این دسترسی، کانتینر نمی‌تواند وارد پوشه شود، حتی اگر بتواند نام آن را لیست کند. دامی که باعث خالی ماندن کل کتابخانه می‌شود، دایرکتوری والد است: اگر uid کانتینر نتواند خودِ mount را پیمایش کند، هرگز به /media/Movies یا /media/Shows نمی‌رسد و تمام کتابخانه‌ها بلافاصله با خطای Access to the path ... is denied در لاگ، خالی نمایش داده می‌شوند. هر پوشهٔ رسانه‌ای که قابل خواندن نباشد، در لاگ ثبت و نادیده گرفته می‌شود؛ بنابراین دسته‌ای از فایل‌ها که با کاربر root کپی شده‌اند، بدون هیچ هشداری از کتابخانه ناپدید می‌شوند. به همین دلیل است که ما از chown به صورت بازگشتی (recursive) استفاده می‌کنیم و بیت execute را روی تمام دایرکتوری‌ها تنظیم می‌کنیم، به جای اینکه فقط یک پوشه را اصلاح کنیم.

فایل docker-compose

services:
  jellyfin:
    image: jellyfin/jellyfin:10
    container_name: jellyfin
    user: "1000:1000"
    restart: unless-stopped
    ports:
      - "127.0.0.1:8096:8096"
    volumes:
      - ./config:/config
      - ./cache:/cache
      - /mnt/media:/media:ro
    environment:
      - JELLYFIN_PublishedServerUrl=https://jellyfin.example.com

خط به خط: user: "1000:1000" همان بخشی است که مجوزهای فایل را تعیین می‌کند و با مالکیت ذکر شده در بالا مطابقت دارد. /config کل سرور، حساب‌های کاربری، کتابخانه‌ها، متادیتا، وضعیت تماشا و غیره را در خود نگه می‌دارد، بنابراین باید قابل نوشتن باشد و همان فایلی است که باید از آن نسخه پشتیبان تهیه کنید. /cache فضای کاری موقت و دورریختنی است. mount مربوط به رسانه یعنی :ro عمداً به صورت read-only تنظیم شده است: Jellyfin به‌طور پیش‌فرض تصاویر و متادیتا را در /config ذخیره می‌کند، بنابراین نیازی به نوشتن در کتابخانه شما ندارد و حالت read-only از فایل‌های شما در برابر حذف تصادفی یا افزونه‌های مخرب محافظت می‌کند. پورت به‌طور عمدی روی 127.0.0.1 تنظیم شده است، زیرا ورود به وب Jellyfin از پروتکل HTTP ساده استفاده می‌کند، بنابراین ما هرگز پورت 8096 را در اینترنت عمومی منتشر نمی‌کنیم. JELLYFIN_PublishedServerUrl آدرسی است که سرور برای کشف خودکار محلی (local autodiscovery) یا همان پخش UDP در شبکه LAN اعلام می‌کند، بنابراین کلاینت‌های خارج از اینترنت آن را نمی‌بینند و صرفاً از URL که در برنامه وارد می‌کنید استفاده می‌کنند. این مقدار را روی آدرسی تنظیم کنید که کلاینت‌ها باید از آن مطلع شوند و انتظار داشته باشید که در دستگاه‌های راه دور، آن URL را به‌صورت دستی وارد کنید.

سرویس را از دایرکتوری compose بالا بیاورید:

docker compose up -d
docker logs -f jellyfin

اجرای اولیه: ویزارد راه‌اندازی و کتابخانه‌ها

از آنجا که پورت به localhost محدود شده است، به‌جای باز کردن حفره در فایروال، از طریق یک SSH tunnel از لپ‌تاپ خود به ویزارد دسترسی پیدا کنید:

ssh -L 8096:127.0.0.1:8096 you@your-vps-ip

اکنون به http://localhost:8096 بروید. ویزارد شما را برای انتخاب زبان و سپس ایجاد یک کاربر مدیر با رمز عبور قوی راهنمایی می‌کند؛ این حساب، سرور شماست، بنابراین از رمز عبور موقت استفاده نکنید. اولین کتابخانه خود را اضافه کنید: نوع محتوا را Movies انتخاب کنید، آن را به /media/Movies (مسیر داخل کانتینر، نه مسیر میزبان) هدایت کنید و همین کار را برای Shows در /media/Shows تکرار کنید. کار را تمام کنید تا Jellyfin اسکن را آغاز کند. نتیجه صحیح، پر شدن پوسترها و عناوین در عرض یک یا دو دقیقه برای یک کتابخانه کوچک است. کتابخانه‌ها را می‌توانید بعداً از طریق Dashboard → Libraries اضافه یا ویرایش کنید و با استفاده از Scan All Libraries، اسکن مجدد را اجبار کنید.

اگر به هر نوع transcoding وابسته هستید، به Dashboard → Playback → Transcoding بروید و مسیر موقت transcode را روی /cache/transcodes تنظیم کنید تا تغییرات روی volume کش ذخیره شود و باعث پر شدن /config نشود. شتاب‌دهنده سخت‌افزاری (hardware acceleration) را روی None باقی بگذارید، زیرا GPU برای شتاب‌دهی وجود ندارد.

دسترسی از راه دور: reverse proxy با TLS، یا نگهداری روی VPN

برای دسترسی به Jellyfin از خارج از شبکه، دو روش امن و یک روش ناامن وجود دارد. روش ناامن، انتشار مستقیم پورت 8096 روی اینترنت است: اطلاعات ورود به‌صورت متن ساده (cleartext) منتقل می‌شود و پورت مذکور ظرف چند ساعت هدف حملات brute-force قرار می‌گیرد.

گزینه A، استفاده از TLS reverse proxy. سرویس Jellyfin را روی یک زیردامنه پشت Traefik با TLS خودکار برای برنامه‌های Docker، یا پشت nginx با گواهی Let's Encrypt صادرشده توسط Certbot قرار دهید. Jellyfin برای به‌روزرسانی‌های لحظه‌ای از WebSockets استفاده می‌کند، بنابراین proxy باید هدرهای upgrade را forward کند. Traefik این کار را به‌صورت خودکار انجام می‌دهد؛ اما در nginx باید این هدرها به‌صراحت تعریف شوند و برای اینکه عملیات upgrade با موفقیت انجام شود، باید از HTTP/1.1 به سمت upstream استفاده کنید:

location / {
    proxy_pass http://127.0.0.1:8096;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

مقدار JELLYFIN_PublishedServerUrl را روی آدرس https:// تنظیم کنید تا autodiscovery محلی، URL صحیح را تبلیغ کند و برنامه‌های راه دور از آدرسی که به آن‌ها می‌دهید استفاده کنند. همچنین fail2ban را برای کند کردن حملات brute-force علیه صفحه ورود اضافه کنید. پس از عمومی کردن سرور، Uptime Kuma را روی آن URL تنظیم کنید تا پیش از کاربران، از قطعی سرویس مطلع شوید.

گزینه B، خصوصی نگه‌داشتن روی VPN. پورت 8096 را به‌هیچ‌وجه منتشر نکنید؛ تنها از طریق تونل WireGuard که روی همان سرور خاتمه می‌یابد به Jellyfin دسترسی پیدا کنید. برای یک محیط خانگی، این ساده‌ترین انتخاب امن است؛ بدون نیاز به گواهی، بدون قرارگیری در معرض اینترنت عمومی و بدون سطح حمله برای brute-force. کانتینر را به آدرس تونل یا localhost متصل (bind) کنید و از طریق VPN به آن وصل شوید. برای راه‌اندازی خودِ تونل، به راهنمای راه‌اندازی WireGuard VPN برای یک VPS خصوصی مراجعه کنید.

تخمین فضای ذخیره‌سازی و پشتیبان‌گیری

بودجه‌بندی را بر اساس کیفیت انجام دهید، نه تعداد فایل‌ها. فیلم‌های 1080p فشرده‌شده هر کدام 4 تا 15 گیگابایت، نسخه‌های remux 1080p بین 20 تا 40 گیگابایت، یک فصل سریال 1080p بین 15 تا 40 گیگابایت و هر محتوای 4K بین 40 تا 100 گیگابایت فضا اشغال می‌کنند. برای آرشیوی شامل چند صد فیلم و تعدادی سریال، به یک volume با ظرفیت 2 تا 4 ترابایت نیاز دارید؛ هزینهٔ تخصیص فضای اضافی در همان ابتدا، بسیار کمتر از مهاجرت داده‌ها در آینده است.

/config کل وضعیت سرور را در بر می‌گیرد، بنابراین تنها چیزی است که حتماً باید از آن پشتیبان تهیه کنید. از آن snapshot بگیرید یا آن را متوقف کرده و با tar آرشیو کنید و نسخهٔ پشتیبان را خارج از سرور نگهداری کنید:

docker compose down
sudo tar czf jellyfin-config-$(date +%F).tgz -C ~/jellyfin config
docker compose up -d

/cache و پوشهٔ transcode قابل جایگزینی هستند. از محتوای رسانه‌ای روی /mnt/media جداگانه پشتیبان بگیرید یا بپذیرید که در صورت از دست رفتن، دوباره قابل تهیه (rippable) هستند؛ اکثر کاربران با توجه به حجم بالای این داده‌ها، گزینهٔ دوم را انتخاب می‌کنند. ارتقاها از نوع docker compose pull && docker compose up -d هستند؛ تگ :10 در بالا در محدودهٔ نسخهٔ اصلی 10.x باقی می‌ماند، بنابراین انتقال به نسخهٔ اصلی بعدی نیازمند تغییر دستی تگ است. پیش از انجام این کار، یادداشت‌های انتشار Jellyfin را مطالعه کنید، زیرا مهاجرت‌های schema کتابخانه معمولاً در نسخه‌های اصلی (major versions) رخ می‌دهند. استفاده از یک تگ ثابت (pinned tag) به همراه یک دایرکتوری وضعیت پشتیبان‌گیری‌شده، دستورالعمل کامل برای هر container همیشه فعال است و همین الگو در حفظ حافظه و زمان‌بندی‌های یک agent خودمیزبان پس از reboot نیز استفاده می‌شود.

حالت‌های شکست و پیام‌های مرتبط

کتابخانه پس از اسکن خالی است. لاگ موجود در Dashboard → Logs (یا ~/jellyfin/config/log/log_*.log) این مورد را نشان می‌دهد:

System.UnauthorizedAccessException: Access to the path '/media/Movies' is denied.

شناسه کاربری (uid) کانتینر نمی‌تواند آن مسیر را بخواند. علت: فایل‌های رسانه‌ای متعلق به root یا uid دیگری غیر از مقدار user: شما هستند، یا دایرکتوری فاقد بیت اجرایی (execute bit) است، یا خود mount والد توسط آن uid قابل پیمایش نیست. راه‌حل: chown -R 1000:1000 /mnt/media، دایرکتوری‌ها را 755، فایل‌ها را 644 کنید و سپس دوباره اسکن نمایید.

پخش ویدیو باعث درگیری شدید CPU و بافر شدن می‌شود. docker stats jellyfin نشان می‌دهد که مصرف CPU نزدیک به 100 درصد ضرب‌در تعداد هسته‌ها است و Dashboard → Playback نشست (session) را به صورت Transcode با سرعتی کمتر از 1.0x فهرست می‌کند. کلاینت در حال پخش مستقیم (direct-play) نیست، بنابراین VPS در حال transcoding نرم‌افزاری با سرعتی کمتر از زمان واقعی است و عقب می‌ماند. علت: کدک یا کانتینر پشتیبانی‌نشده، رندر کردن زیرنویس (burn-in) یا tone-mapping برای HDR. راه‌حل: از کلاینتی استفاده کنید که از پخش مستقیم پشتیبانی می‌کند، منابع را در فرمت H.264/AAC نگه دارید، از زیرنویس‌های متنی (SRT) به جای زیرنویس‌های تصویری (PGS/VOBSUB) که باعث تحمیل رندر می‌شوند استفاده کنید و محتوای 4K HDR را کلاً روی سروری که فقط CPU دارد اجرا نکنید.

پیام "No compatible streams are available." متن کامل معمولاً به این صورت است: "This client isn't compatible with the media and the server isn't sending a compatible media format." کلاینت منبع را رد کرده و transcoding جایگزین نیز برای شروع شکست خورده است. علت: دستور ffmpeg خراب، فایل غیرقابل خواندن، یا پروفایل کاربری که تبدیل ویدیو را مسدود کرده است. راه‌حل: خط دستور ffmpeg را در Dashboard → Logs بخوانید، مطمئن شوید که فایل اصلاً پخش می‌شود، اگر به transcoding وابسته هستید مجوزهای پخش کاربر را بررسی کنید و برای اطمینان از اینکه مشکل از ناسازگاری کدک مرورگر نیست، از کلاینت دیگری استفاده کنید.

فیلم‌ها پوستر ندارند یا پوستر اشتباه نمایش داده می‌شود. متادیتا مطابقت نداشته است. علت: فیلم در پوشه اختصاصی خود Name (Year) نیست، پوشه فصل به جای Season 01 با نام S01 نام‌گذاری شده، قسمت‌ها در قالب S01E01 نیستند یا سال تولید حذف شده است. راه‌حل: نام‌گذاری را به ساختار بالا تغییر دهید، سپس Refresh metadata → Replace all را بزنید یا از گزینه Identify روی یک آیتم خاص استفاده کنید تا ورودی صحیح TMDB/TVDB را مشخص نمایید.

FAQ

آیا یک VPS می‌تواند بدون GPU ویدیو را Transcode کند؟

بله، اما فقط با استفاده از CPU و این کار هزینه‌بر است. یک Transcode نرم‌افزاری 1080p می‌تواند چندین vCPU را کاملاً درگیر کند و معمولاً پردازش 4K یا HEVC نمی‌تواند با سرعت پخش زنده (Real-time) همگام شود، در نتیجه پخش با وقفه (Buffer) مواجه می‌شود. بهترین راهکار، پرهیز از Transcoding است: کتابخانه خود را با فرمت H.264/AAC نگه دارید و از کلاینت‌هایی استفاده کنید که از قابلیت Direct-play پشتیبانی می‌کنند تا VPS فقط نقش انتقال‌دهنده بایت‌ها را داشته باشد. تنها در صورتی یک نمونه (Instance) دارای GPU اجاره کنید که واقعاً به Transcoding لحظه‌ای نیاز دارید.

چرا کتابخانه Jellyfin من پس از اسکن خالی است؟

تقریباً همیشه مشکل از مجوزها (Permissions) است. تصویر رسمی jellyfin/jellyfin با هر user: که تعیین کرده‌اید (یا root) اجرا می‌شود؛ اگر فایل‌ها توسط آن uid قابل خواندن نباشند، لاگ‌های اسکن Access to the path ... is denied را ثبت کرده و از آن‌ها عبور می‌کند. مالکیت فایل‌ها را با chown -R 1000:1000 /mnt/media اصلاح کنید، به دایرکتوری‌ها بیت اجرایی (755) بدهید، دوباره اسکن کنید و دایرکتوری والد را نیز بررسی کنید؛ زیرا اگر uid کانتینر نتواند از /mnt/media عبور کند، هرگز به پوشه‌های کتابخانه نمی‌رسد و همه چیز خالی نمایش داده می‌شود. دومین دلیل رایج، ساختار پوشه‌بندی است که با انتظارات Jellyfin مطابقت ندارد.

چگونه به صورت امن و از راه دور به Jellyfin دسترسی داشته باشم؟

دو گزینه مناسب وجود دارد. آن را پشت یک Reverse Proxy با TLS روی یک زیردامنه قرار دهید تا ورود و استریم رمزنگاری شوند و fail2ban را اضافه کنید؛ هرگز پورت 8096 را به صورت خام در معرض اینترنت قرار ندهید، زیرا رمز عبور شما را به صورت متن ساده (Cleartext) ارسال می‌کند. یا آن را کاملاً خصوصی نگه دارید و فقط از طریق VPN به آن دسترسی پیدا کنید که ساده‌ترین انتخاب امن برای مصارف خانگی است. آدرس عمومی را مستقیماً به اپلیکیشن‌ها بدهید، زیرا قابلیت Autodiscovery یک پخش شبکه محلی (Broadcast) است و به کلاینت‌هایی که از طریق اینترنت متصل می‌شوند، نمی‌رسد.

یک VPS برای Jellyfin به چه مقدار دیسک و پهنای باند نیاز دارد؟

میزان دیسک به کیفیت بستگی دارد: برای هر فیلم 1080p فشرده 4-15 گیگابایت، برای هر Remux حدود 20-40 گیگابایت و برای 4K حدود 40-100 گیگابایت در نظر بگیرید، بنابراین اکثر کتابخانه‌ها به یک Block Volume با ظرفیت 2-4 ترابایت نیاز دارند. پهنای باند توسط نرخ بیت (Bitrate) در حالت Direct-play تعیین می‌شود که برای هر استریم 1080p حدود 8-12 مگابیت بر ثانیه است و برای 4K بسیار بیشتر؛ بنابراین اطمینان حاصل کنید که سرعت پورت شما پاسخگوی تعداد بینندگان همزمان است و سقف انتقال ماهانه را نیز زیر نظر داشته باشید. اگر قصد Transcoding دارید، ظرفیت CPU بیشتری در نظر بگیرید؛ اما اگر قصد استفاده از Direct-play دارید، پهنای باند را نسبت به تعداد هسته‌ها در اولویت قرار دهید.

آیا اجرای Jellyfin روی یک VPS قانونی است؟

Jellyfin خود یک نرم‌افزار آزاد و متن‌باز است و اجرای آن کاملاً قانونی است. آنچه اهمیت دارد محتواست: فقط رسانه‌هایی را استریم کنید که مالک آن‌ها هستید یا مجوز نگهداری آن‌ها را دارید؛ مانند ریپ‌های دیسک شخصی، ضبط‌ها یا فایل‌هایی که حق استفاده از آن‌ها را دارید. Jellyfin هیچ رسانه‌ای را به همراه ندارد و راهی برای دریافت آن فراهم نمی‌کند؛ این نرم‌افزار صرفاً یک پخش‌کننده برای کتابخانه‌ای است که از قبل در اختیار دارید.