SSD Nodes Learn Hosting plans →
নির্দেশিকা Matt Connorদ্বারা Matt Connor · আপডেট করা হয়েছে 2026-08-26

VPS-এ Jellyfin সেটআপ করার নিয়ম

Docker ব্যবহার করে VPS-এ Jellyfin ইনস্টল করার পূর্ণাঙ্গ গাইড। ব্লক স্টোরেজ মাউন্ট, ফাইল পারমিশন ঠিক করা এবং CPU ট্রান্সকোডিং এড়াতে ডাইরেক্ট প্লে সেটিংসের সঠিক নিয়মগুলো এখানে জানুন।

আপনি যা তৈরি করছেন

একটি VPS-এ Jellyfin মিডিয়া সার্ভার: একটি কন্টেইনার, তিনটি ভলিউম এবং আপনার সিনেমা ও শোগুলোর জন্য একটি ব্লক-স্টোরেজ ডিস্ক, যা যেকোনো ব্রাউজার বা Jellyfin অ্যাপ থেকে ব্যবহার করা যাবে। এই ইনস্টলেশনটি একটি পনেরো লাইনের compose ফাইল। পরবর্তীতে যা কিছু ভুল হয়, তা মূলত দুটি কারণে ঘটে: কন্টেইনারের ফাইল পড়ার অনুমতি না থাকা এবং GPU-বিহীন VPS-কে এমন ভিডিও ট্রান্সকোড করতে বলা যা তার করার কথা নয়। এই গাইডের বেশিরভাগ অংশ এই দুটি বিষয়ের ওপর আলোকপাত করে, কারণ সাপোর্ট টিকিটগুলো মূলত এখান থেকেই আসে।

Jellyfin সম্পূর্ণ বিনামূল্যে এবং ওপেন সোর্স, যেখানে কোনো অ্যাকাউন্ট, পেইড ফিচার বা টেলিমেট্রি নেই। এই কারণেই এটি 2026 সালে সেলফ-হোস্টিংয়ের যোগ্য বিষয়গুলোর তালিকায় প্রায় সবসময়ই থাকে। এটি আপনার নিজের সংগ্রহ করা মিডিয়া প্লে করে। এটি কোনো কন্টেন্ট সরবরাহ করে না এবং এই গাইডটি কোনো কন্টেন্ট সংগ্রহের বিষয়ে নয়।

ট্রান্সকোডিংয়ের বাস্তবতা, কোনো কিছু ভাড়া নেওয়ার আগে

এটি আগে পড়ুন, কারণ এটি আপনার কেনাকাটার সিদ্ধান্ত বদলে দেবে। আপনি প্লে বাটনে চাপ দিলে একটি মিডিয়া সার্ভার দুটি কাজের একটি করে। Direct play ফাইলটিকে যেমন আছে তেমন স্ট্রিম করে: VPS ডিস্ক থেকে বাইট পড়ে এবং তা নেটওয়ার্কে পাঠিয়ে দেয়, এতে প্রায় কোনো CPU খরচ হয় না। Transcoding ভিডিওটিকে তাৎক্ষণিকভাবে নতুন রেজোলিউশন বা নতুন কোডেকের সাথে এনকোড করে অথবা সাবটাইটেল যুক্ত করে, আর এটি পুরোপুরি CPU-এর কাজ।

সাধারণত একটি VPS-এ কোনো GPU থাকে না। তাই প্রতিটি ট্রান্সকোড libx264/libx265 ব্যবহার করে CPU-তে চলে এবং সফটওয়্যার এনকোডিং বেশ ব্যয়বহুল। একটি 1080পি H.264 ট্রান্সকোড একাধিক শেয়ারড vCPU-কে ব্যস্ত করে ফেলতে পারে; 4কে (4K) বা HEVC ট্রান্সকোড সাধারণত রিয়েল-টাইমে চলতে পারে না, ফলে প্লেব্যাক আটকে যায় এবং বাফারিং হতে থাকে। হার্ডওয়্যার ট্রান্সকোডিং, যা ইন্টেল iGPU বা এনভিডিয়া কার্ডযুক্ত হোম বক্সে খুব সহজ, তা আপনার জন্য উপলব্ধ নয় যদি না আপনার প্রোভাইডার GPU ইনস্ট্যান্স ভাড়া দেয়।

তাই VPS-এ পুরো কৌশলের মূল কথা হলো: ট্রান্সকোডিং এড়িয়ে চলুন। আপনার লাইব্রেরিকে এমন কোডেকের মধ্যে রাখুন যা আপনার ক্লায়েন্ট সরাসরি প্লে করতে পারে, যেমন H.264 ভিডিও, AAC বা AC3 অডিও, MP4 বা MKV কন্টেইনারে। এমন ক্লায়েন্ট অ্যাপ বেছে নিন যা সরাসরি প্লে করতে পারে: অ্যান্ড্রয়েড টিভি, আইওএস (iOS) এবং রোকু (Roku)-এর জন্য নেটিভ Jellyfin অ্যাপ, এছাড়া Infuse, Kodi এবং ডেস্কটপ Jellyfin Media Player। এটি করলে VPS-কে কখনোই ffmpeg ব্যবহার করতে হবে না এবং একটি সাধারণ 2 vCPU-এর বক্স দিয়ে একসাথে কয়েকজনকে স্ট্রিম করা সম্ভব। ট্রান্সকোডিংয়ের পরিকল্পনা করলে আপনার অনেক বড় ও ব্যয়বহুল বক্স প্রয়োজন হবে, আর সেক্ষেত্রেও 4কে (4K) স্ট্রিম করা ঝুঁকিপূর্ণ।

ব্যান্ডউইথের হিসাবও করুন, কারণ এটিও একটি অপ্রত্যাশিত বিষয়। Direct play হলে ফাইলটি তার নিজস্ব bitrate-এ পাঠানো হয়। Compressed 1080p ফাইল সাধারণত 8-12 Mbps ব্যবহার করে; 1080p Blu-ray remux 20-30 Mbps; 4K HDR 40-80 Mbps। 10 Mbps-এর 3টি ফাইল 3 জন ব্যবহারকারী direct play করলে আপনার VPS থেকে sustained upload 30 Mbps হবে। আপনার plan-এ 2টি সংখ্যা পরীক্ষা করুন: port speed (এটি কি upstream-এ 30 Mbps পাঠাতে পারে?) এবং মাসিক transfer cap। 10 Mbps-এর 2 ঘণ্টার একটি film পাঠাতে প্রায় 9 GB data লাগে। তাই metered 1 TB/month allowance-এ মাসে 100টির কিছু বেশি এমন film পাঠানো যায়, অর্থাৎ দিনে 3 বা 4টি। কোনো household 4K content দেখলে bitrate 4 থেকে 8 গুণ বেশি হওয়ায় allowance আরও দ্রুত শেষ হবে। একই box থেকে বাইরে পাঠানো অন্য সব traffic-ও এই একই budget-এর মধ্যে ধরুন। এর মধ্যে self-hosted RustDesk relay-ও রয়েছে। 2টি peer সরাসরি connect করতে না পারলে এটি একটি সম্পূর্ণ remote desktop session বহন করে।

পূর্বশর্ত

  • root বা sudo সুবিধা সম্পন্ন একটি নতুন Ubuntu 24.04 KVM VPS, যেখানে Docker এবং Compose plugin ইনস্টল করা আছে।
  • আপনার লাইব্রেরির আকার অনুযায়ী মিডিয়া ফাইলের জন্য একটি block-storage volume (নিচে sizing দেখুন)। VPS-এর সাথে যে ছোট root disk দেওয়া হয়, সেখানে সিনেমা রাখা উচিত নয়।
  • আপনি যদি পাবলিক HTTPS অ্যাক্সেস চান তবে একটি domain name, অথবা যদি পুরো বিষয়টি ব্যক্তিগত রাখতে চান তবে একই VPS-এ WireGuard VPN
  • এমন মিডিয়া ফাইল যা স্ট্রিম করার আইনি অধিকার আপনার আছে, যেমন আপনার নিজের করা rip, নিজের রেকর্ড করা ফাইল বা আপনার মালিকানাধীন ফাইল।

প্রথমে ব্লক স্টোরেজ মাউন্ট করুন

আপনার প্রোভাইডারের প্যানেল থেকে ভলিউমটি অ্যাটাচ করুন, তারপর সেটিকে খুঁজে বের করে মাউন্ট করুন। lsblk থেকে ডিভাইসের নাম সংগ্রহ করুন, এটি সাধারণত /dev/sdb বা /dev/vdb এর মতো হবে, কখনোই রুট ডিস্ক নয়।

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

ডিভাইস লেটার রিবুটের সময় পরিবর্তিত হতে পারে এবং ভুল ডিস্ক ফরম্যাট বা মাউন্ট হওয়ার ঝুঁকি থাকে, তাই /dev/sdb ব্যবহার না করে UUID দিয়ে মাউন্ট করুন। /etc/fstab ফাইলে একটি লাইন যোগ করুন:

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

nofail গুরুত্বপূর্ণ: এটি ছাড়া, ব্লক ভলিউমটি কোনো কারণে ডিটাচ হয়ে গেলে সার্ভার বুট হতে অস্বীকার করবে এবং ইমার্জেন্সি শেলে চলে যাবে। এখানে সবচেয়ে বড় ভুল হলো যে ভলিউমে আগে থেকেই ডেটা আছে তাতে mkfs.ext4 চালানো, কারণ এটি সব ডেটা মুছে ফেলে। শুধুমাত্র নতুন ভলিউম ফরম্যাট করুন; যদি ডিস্কে আগে থেকেই আপনার লাইব্রেরি থাকে, তবে সরাসরি 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) কেবল সাজানোর জন্য নয়, এটি রিমেক সিনেমাগুলোকে আলাদা করতে সাহায্য করে যাতে মেটাডেটা ম্যাচিং সঠিক হয়। Movies এবং Shows-কে আলাদা টপ-লেভেল ফোল্ডার হিসেবে রাখুন, কারণ প্রতিটি ফোল্ডার Jellyfin-এ নির্দিষ্ট কন্টেন্ট টাইপের একটি লাইব্রেরি হিসেবে কাজ করে এবং এদের মিশিয়ে ফেললে মেটাডেটা প্রোভাইডার বিভ্রান্ত হয়। Jellyfin চাইলে ছবির জন্য তৃতীয় একটি ফোল্ডারও ইনডেক্স করতে পারে, কিন্তু একটি ডেডিকেটেড ফটো সার্ভারের তুলনায় এটি খুব একটা কার্যকর নয়। তাই আপনার অ্যালবামগুলো গুরুত্বপূর্ণ হলে সেগুলোর জন্য PhotoPrism বা Immich ব্যবহার করুন এবং এই সার্ভারটিকে শুধু সিনেমা ও টিভি সিরিজের জন্য বরাদ্দ রাখুন।

অনুমতি: লাইব্রেরি খালি থাকার প্রধান কারণ

এটি এমন একটি ভুল ধারণা যা ব্যবহারকারীদের অনেক সময় নষ্ট করে। অফিসিয়াল jellyfin/jellyfin ইমেজ PUID/PGID এনভায়রনমেন্ট ভেরিয়েবল সমর্থন করে না, এগুলো শুধুমাত্র LinuxServer.io ইমেজের (lscr.io/linuxserver/jellyfin) জন্য প্রযোজ্য। অফিসিয়াল ইমেজে আপনি compose ফাইলে user: কি (key) ব্যবহার করে ইউজার নিয়ন্ত্রণ করেন, এবং এটি বাদ দিলে কন্টেইনারটি root হিসেবে চলে। আপনি যেটিই ব্যবহার করুন না কেন, নিয়ম একই: কন্টেইনারটি যে uid/gid-এ চলছে, তাকে অবশ্যই প্রতিটি মিডিয়া ডিরেক্টরি পড়ার এবং সেগুলোর ভেতর দিয়ে যাওয়ার (traverse) ক্ষমতা রাখতে হবে।

আমরা uid/gid 1000 হিসেবে চালাব, যা একটি সাধারণ 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

ডিরেক্টরিগুলোর জন্য শুধুমাত্র রিড (read) নয়, execute বিট (755-এ x) প্রয়োজন। এটি ছাড়া কন্টেইনারটি ফোল্ডারের নাম দেখতে পেলেও ভেতরে প্রবেশ করতে পারে না। পুরো লাইব্রেরি খালি হয়ে যাওয়ার মূল কারণ হলো প্যারেন্ট ডিরেক্টরি: যদি কন্টেইনারের uid মাউন্ট পয়েন্টের ভেতর দিয়ে যেতে না পারে, তবে এটি কখনোই /media/Movies বা /media/Shows-এ পৌঁছাতে পারে না এবং লগে Access to the path ... is denied ত্রুটিসহ পুরো লাইব্রেরি খালি দেখায়। যে কোনো একটি মিডিয়া ফোল্ডার পড়তে না পারলে সেটি লগে রেকর্ড হয় এবং এড়িয়ে যাওয়া হয়, তাই রুট হিসেবে কপি করা ফাইলগুলো লাইব্রেরি থেকে নীরবে অদৃশ্য হয়ে যায়। এই কারণেই আমরা একটি ফোল্ডার ঠিক করার পরিবর্তে রিকার্সিভলি (recursively) chown করি এবং প্রতিটি ডিরেক্টরিতে 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 ফোল্ডারটিতে পুরো সার্ভার, অ্যাকাউন্ট, লাইব্রেরি, মেটাডেটা এবং ওয়াচ স্টেট থাকে, তাই এটি অবশ্যই রাইট-অ্যাবল (writable) হতে হবে এবং ব্যাকআপ নেওয়ার সময় এটিই মূল অংশ। /cache হলো অস্থায়ী কাজের জায়গা। মিডিয়া মাউন্টটি ইচ্ছাকৃতভাবে :ro (read-only) রাখা হয়েছে: Jellyfin ডিফল্টভাবে আর্টওয়ার্ক এবং মেটাডেটা /config-এর অধীনে সংরক্ষণ করে, তাই আপনার লাইব্রেরিতে কোনো কিছু লেখার প্রয়োজন হয় না। রিড-অনলি মোড আপনার ফাইলগুলোকে ভুলবশত মুছে ফেলা বা ত্রুটিপূর্ণ প্লাগইন থেকে রক্ষা করে। পোর্টটি ইচ্ছাকৃতভাবে 127.0.0.1-এ বাইন্ড করা হয়েছে, কারণ Jellyfin-এর ওয়েব লগইন সাধারণ HTTP-তে চলে, তাই আমরা কখনোই 8096 পোর্টটি সরাসরি পাবলিক ইন্টারনেটে উন্মুক্ত করি না। JELLYFIN_PublishedServerUrl হলো সেই ঠিকানা যা সার্ভার লোকাল অটো-ডিসকভারি বা LAN UDP ব্রডকাস্টের জন্য প্রচার করে। ইন্টারনেটের মাধ্যমে সংযুক্ত ক্লায়েন্টরা এটি দেখতে পায় না এবং তারা সরাসরি আপনার অ্যাপে টাইপ করা 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 ব্যবহার করে জোরপূর্বক পুনরায় স্ক্যান করতে পারবেন।

যদি আপনি কোনো ধরনের ট্রান্সকোডিংয়ের ওপর নির্ভর করেন, তবে Dashboard → Playback → Transcoding খুলুন এবং ট্রান্সকোড টেম্প পাথটিকে /cache/transcodes-এ সেট করুন, যাতে ডেটা /config-এর আকার বৃদ্ধি না করে ক্যাশ ভলিউমে জমা হয়। হার্ডওয়্যার এক্সিলারেশন None-এ রাখুন, কারণ এখানে এক্সিলারেট করার মতো কোনো GPU নেই।

রিমোট অ্যাক্সেস: TLS রিভার্স প্রক্সি, অথবা VPN-এর মাধ্যমে সীমাবদ্ধ রাখা

বাইরে থেকে Jellyfin-এ পৌঁছানোর দুটি নিরাপদ উপায় আছে এবং একটি অনিরাপদ উপায় রয়েছে যা এড়িয়ে চলতে হবে। অনিরাপদ উপায়টি হলো সরাসরি ইন্টারনেটে 8096 পোর্ট উন্মুক্ত করে দেওয়া: এতে লগইন তথ্য প্লেইন টেক্সটে আদান-প্রদান হয় এবং কয়েক ঘণ্টার মধ্যেই পোর্টটি ব্রুট-ফোর্স আক্রমণের শিকার হয়।

বিকল্প A, TLS রিভার্স প্রক্সি। Jellyfin-কে একটি সাবডোমেইনের অধীনে Traefik with automatic TLS for your Docker apps-এর পেছনে রাখুন, অথবা Certbot দ্বারা ইস্যু করা Let's Encrypt certificate issued by Certbot সহ nginx-এর পেছনে রাখুন। Jellyfin রিয়েল-টাইম আপডেটের জন্য WebSockets ব্যবহার করে, তাই প্রক্সিকে অবশ্যই upgrade হেডারগুলো ফরওয়ার্ড করতে হবে। Traefik এটি স্বয়ংক্রিয়ভাবে করে; nginx-এর ক্ষেত্রে এগুলো স্পষ্টভাবে উল্লেখ করতে হয় এবং আপস্ট্রিমের সাথে HTTP/1.1 ব্যবহার করতে হয়, অন্যথায় আপগ্রেড সম্পন্ন হয় না:

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:// ঠিকানায় সেট করুন যাতে যেকোনো লোকাল অটো-ডিসকভারি সঠিক URL প্রচার করে, রিমোট অ্যাপগুলো আপনার দেওয়া ঠিকানা ব্যবহার করে এবং লগইনের বিরুদ্ধে fail2ban to slow brute-force attempts যোগ করুন। সার্ভারটি পাবলিক করার পর, Uptime Kuma-কে সেই URL-এ পয়েন্ট করে রাখুন যাতে আপনার ব্যবহারকারীদের আগেই আপনি ডাউনটাইম সম্পর্কে জানতে পারেন।

বিকল্প B, VPN-এর মাধ্যমে ব্যক্তিগত রাখা। 8096 পোর্টটি মোটেও উন্মুক্ত করবেন না; শুধুমাত্র একই বক্সে টার্মিনেট হওয়া WireGuard টানেলের মাধ্যমে Jellyfin-এ প্রবেশ করুন। একটি পরিবারের জন্য এটিই সবচেয়ে সহজ এবং নিরাপদ পছন্দ, এতে কোনো সার্টিফিকেটের প্রয়োজন নেই, পাবলিক এক্সপোজার নেই এবং ব্রুট-ফোর্স আক্রমণের ঝুঁকি নেই। কন্টেইনারটিকে টানেল অ্যাড্রেস বা localhost-এ বাইন্ড করুন এবং VPN-এর মাধ্যমে সংযোগ স্থাপন করুন। টানেল তৈরির জন্য WireGuard VPN setup for a private VPS দেখুন।

স্টোরেজ সাইজিং এবং ব্যাকআপ

ফাইলের সংখ্যার ওপর ভিত্তি করে নয়, বরং গুণমানের ওপর ভিত্তি করে বাজেট নির্ধারণ করুন। কম্প্রেসড 1080p ফিল্মের সাইজ সাধারণত 4-15 GB হয়; একটি 1080p remux 20-40 GB; 1080p টিভি সিরিজের একটি সিজন 15-40 GB; এবং 4K কন্টেন্টের যেকোনো ফাইলের সাইজ প্রতি ফিল্মে 40-100 GB হতে পারে। কয়েকশ ফিল্ম এবং কিছু টিভি শো-এর লাইব্রেরির জন্য 2-4 TB ভলিউম প্রয়োজন। পরবর্তীতে মাইগ্রেট করার চেয়ে একবারেই বেশি ব্লক ভলিউম বরাদ্দ রাখা সাশ্রয়ী।

/config হলো পুরো সার্ভারের স্টেট, তাই এটিই একমাত্র জিনিস যা আপনাকে অবশ্যই ব্যাকআপ রাখতে হবে। স্ন্যাপশট নিন অথবা stop-and-tar কমান্ড ব্যবহার করে কপিটি সার্ভারের বাইরে সংরক্ষণ করুন:

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

/cache এবং ট্রান্সকোড ফোল্ডারটি ফেলে দেওয়ার মতো বা অস্থায়ী। /mnt/media-এ থাকা মিডিয়া ফাইলগুলো আপনি আলাদাভাবে ব্যাকআপ রাখতে পারেন অথবা এগুলো পুনরায় রি-র‍্যাপ (re-rippable) করা যাবে বলে ধরে নিতে পারেন; ফাইলের বিশাল সাইজের কারণে অধিকাংশ মানুষ দ্বিতীয় পদ্ধতিটিই বেছে নেয়। আপগ্রেডগুলো হলো docker compose pull && docker compose up -d; উপরের :10 ট্যাগটি 10.x মেজর ভার্সনের মধ্যেই সীমাবদ্ধ থাকে, তাই পরবর্তী মেজর ভার্সনে যাওয়ার জন্য আপনাকে সচেতনভাবে ট্যাগ এডিট করতে হবে। Jellyfin রিলিজ নোটগুলো আগে পড়ে নিন, কারণ মেজর ভার্সন পরিবর্তনের সময় লাইব্রেরি স্কিমা মাইগ্রেশন হতে পারে। একটি পিন করা ট্যাগ এবং একটি ব্যাকআপ করা স্টেট ডিরেক্টরি হলো যেকোনো অলওয়েজ-অন কন্টেইনারের মূল ভিত্তি, এবং এটিই রিবুটের পরেও সেলফ-হোস্টেড এজেন্টের মেমোরি ও শিডিউল সচল রাখার পেছনের সাধারণ প্যাটার্ন।

ব্যর্থতার ধরন এবং যে বার্তাগুলো আপনি দেখবেন

স্ক্যান করার পর লাইব্রেরি খালি দেখাচ্ছে। Dashboard → Logs (অথবা ~/jellyfin/config/log/log_*.log)-এ থাকা লগগুলো দেখুন:

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

কন্টেইনারের uid ওই পাথে (path) প্রবেশ করতে পারছে না। কারণ: মিডিয়া ফাইলগুলো root অথবা আপনার user: ভ্যালু থেকে ভিন্ন কোনো uid-এর মালিকানাধীন, ডিরেক্টরিতে execute বিট নেই, অথবা মূল মাউন্ট পয়েন্টটি ওই uid-এর জন্য প্রবেশযোগ্য নয়। সমাধান: chown -R 1000:1000 /mnt/media করুন, ডিরেক্টরিগুলোর জন্য 755 এবং ফাইলগুলোর জন্য 644 কমান্ড চালান, তারপর পুনরায় স্ক্যান করুন।

প্লেব্যাক করার সময় CPU-এর ব্যবহার বেড়ে যাচ্ছে এবং বাফারিং হচ্ছে। docker stats jellyfin-এ CPU-এর ব্যবহার আপনার কোর সংখ্যার তুলনায় 100% এর কাছাকাছি দেখাচ্ছে এবং Dashboard → Playback-এ সেশনটিকে Transcode হিসেবে দেখাচ্ছে, যার গতি 1.0x-এর নিচে। ক্লায়েন্ট সরাসরি প্লে (direct-play) করতে পারছে না, তাই VPS রিয়েল-টাইমের চেয়ে ধীরগতিতে CPU-ট্রান্সকোডিং করছে এবং ব্যর্থ হচ্ছে। কারণ: অসমর্থিত কোডেক বা কন্টেইনার, সাবটাইটেল বার্ন-ইন, অথবা HDR টোন-ম্যাপিং। সমাধান: সরাসরি প্লে করতে পারে এমন ক্লায়েন্টে সুইচ করুন, সোর্স ফাইলগুলো H.264/AAC ফরম্যাটে রাখুন, image সাবটাইটেল (PGS/VOBSUB) এর পরিবর্তে text সাবটাইটেল (SRT) ব্যবহার করুন (কারণ ইমেজ সাবটাইটেল বার্ন-ইন করতে বাধ্য করে), এবং শুধুমাত্র CPU আছে এমন বক্সে 4K HDR চালানো থেকে বিরত থাকুন।

"No compatible streams are available." সম্পূর্ণ বার্তাটি সাধারণত এমন হয়: "This client isn't compatible with the media and the server isn't sending a compatible media format." ক্লায়েন্ট সোর্স ফাইলটিকে প্রত্যাখ্যান করেছে এবং ফলব্যাক ট্রান্সকোডও শুরু হতে ব্যর্থ হয়েছে। কারণ: ত্রুটিপূর্ণ ffmpeg কমান্ড, ফাইলটি পড়া যাচ্ছে না, অথবা ব্যবহারকারীর প্রোফাইলে ভিডিও কনভার্সন ব্লক করা আছে। সমাধান: Dashboard → Logs-এ ffmpeg লাইনটি পড়ুন, ফাইলটি আদৌ প্লে হয় কি না নিশ্চিত করুন, ট্রান্সকোডিংয়ের ওপর নির্ভর করলে ব্যবহারকারীর প্লেব্যাক পারমিশন চেক করুন, এবং ব্রাউজারের কোডেক সংক্রান্ত সমস্যা এড়াতে অন্য একটি ক্লায়েন্ট ব্যবহার করে দেখুন।

চলচ্চিত্রের পোস্টার নেই বা ভুল পোস্টার দেখাচ্ছে। মেটাডেটা মেলেনি। কারণ: মুভিটি তার নিজস্ব Name (Year) ফোল্ডারে নেই, সিজন ফোল্ডারের নাম Season 01-এর পরিবর্তে S01 দেওয়া হয়েছে, এপিসোডগুলো S01E01 ফরম্যাটে নেই, অথবা মুক্তির বছর উল্লেখ করা নেই। সমাধান: উপরের লেআউট অনুযায়ী নাম পরিবর্তন করুন, তারপর Refresh metadata → Replace all করুন, অথবা সঠিক TMDB/TVDB এন্ট্রি নির্বাচন করতে কোনো একটি আইটেমের ওপর Identify ব্যবহার করুন।

FAQ

GPU ছাড়া কি VPS-এ ভিডিও ট্রান্সকোড করা সম্ভব?

হ্যাঁ, তবে এটি শুধুমাত্র CPU ব্যবহার করে করতে হয় এবং এটি বেশ ব্যয়বহুল। একটি 1080পি (1080p) সফটওয়্যার ট্রান্সকোড একাধিক vCPU-কে ব্যস্ত করে ফেলতে পারে এবং 4কে (4K) বা HEVC সাধারণত রিয়েল-টাইমে চলতে পারে না, যার ফলে প্লেব্যাক বাফার করে। সবচেয়ে ভালো উপায় হলো ট্রান্সকোডিং এড়িয়ে চলা: আপনার লাইব্রেরি H.264/AAC ফরম্যাটে রাখুন এবং এমন ক্লায়েন্ট অ্যাপ ব্যবহার করুন যা সরাসরি প্লে (direct-play) করতে পারে, যাতে VPS শুধুমাত্র বাইট স্ট্রিম করে। শুধুমাত্র যদি আপনার অন-দ্য-ফ্লাই (on-the-fly) ট্রান্সকোডিংয়ের প্রয়োজন হয়, তবেই GPU ইনস্ট্যান্স ভাড়া নিন।

স্ক্যান করার পর আমার Jellyfin লাইব্রেরি খালি দেখাচ্ছে কেন?

এর কারণ প্রায় সবসময়ই পারমিশন বা অনুমতির সমস্যা। অফিসিয়াল jellyfin/jellyfin ইমেজটি আপনার সেট করা user: (অথবা root) হিসেবে চলে। যদি ফাইলগুলো সেই uid-এর মাধ্যমে পড়া না যায়, তবে স্ক্যান লগ Access to the path ... is denied দেখায় এবং ফাইলগুলো এড়িয়ে যায়। chown -R 1000:1000 /mnt/media ব্যবহার করে মালিকানা ঠিক করুন, ডিরেক্টরিগুলোতে এক্সিকিউট বিট (755) দিন এবং পুনরায় স্ক্যান করুন। প্যারেন্ট ডিরেক্টরিও চেক করুন, কারণ কন্টেইনারের uid যদি /mnt/media-এর ভেতর দিয়ে যেতে না পারে, তবে এটি লাইব্রেরি ফোল্ডারে পৌঁছাতে পারবে না এবং সবকিছু খালি দেখাবে। দ্বিতীয় সাধারণ কারণ হলো ফোল্ডার লেআউট, যা Jellyfin-এর প্রত্যাশিত ফরম্যাটের সাথে মেলে না।

আমি কীভাবে নিরাপদে দূর থেকে Jellyfin অ্যাক্সেস করব?

দুটি ভালো উপায় আছে। একটি হলো TLS রিভার্স প্রক্সির পেছনে একটি সাবডোমেইনে এটি রাখা, যাতে লগইন এবং স্ট্রিম এনক্রিপ্টেড থাকে এবং fail2ban যোগ করা। কখনোই সরাসরি পোর্ট 8096 উন্মুক্ত করবেন না, কারণ এটি পাসওয়ার্ড প্লেইন টেক্সটে পাঠায়। অথবা, এটিকে সম্পূর্ণ ব্যক্তিগত রাখুন এবং শুধুমাত্র VPN-এর মাধ্যমে অ্যাক্সেস করুন, যা পরিবারের ব্যবহারের জন্য সবচেয়ে সহজ এবং নিরাপদ উপায়। অ্যাপগুলোতে সরাসরি পাবলিক অ্যাড্রেস দিন, কারণ অটো-ডিসকভারি শুধুমাত্র লোকাল নেটওয়ার্ক ব্রডকাস্টের জন্য কাজ করে, তাই এটি ইন্টারনেটের মাধ্যমে আসা ক্লায়েন্টদের কাছে পৌঁছায় না।

একটি Jellyfin VPS-এর জন্য কতটুকু ডিস্ক এবং ব্যান্ডউইথ প্রয়োজন?

ডিস্কের চাহিদা নির্ভর করে কোয়ালিটির ওপর: কম্প্রেসড 1080পি (1080p) মুভির জন্য 4-15 জিবি, রিমাক্স (remux)-এর জন্য 20-40 জিবি এবং 4কে (4K)-এর জন্য 40-100 জিবি বাজেট রাখুন। তাই বেশিরভাগ লাইব্রেরির জন্য 2-4 টিবি ব্লক ভলিউম প্রয়োজন। ব্যান্ডউইথ নির্ভর করে ডিরেক্ট-প্লে বিটরেটের ওপর, যা 1080পি স্ট্রিমের জন্য 8-12 এমবিপিএস (Mbps) এবং 4কে-এর জন্য আরও অনেক বেশি। তাই নিশ্চিত করুন যে আপনার পোর্ট স্পিড একই সাথে কতজন দর্শক দেখছে তা সামলাতে পারে এবং মাসিক ডেটা লিমিটের দিকে নজর রাখুন। যদি ট্রান্সকোড করার পরিকল্পনা থাকে তবে CPU-এর বাড়তি ক্ষমতা রাখুন; আর যদি ডিরেক্ট-প্লে করার পরিকল্পনা থাকে তবে কোরের চেয়ে ব্যান্ডউইথকে অগ্রাধিকার দিন।

VPS-এ Jellyfin চালানো কি বৈধ?

Jellyfin নিজে একটি ফ্রি এবং ওপেন-সোর্স সফটওয়্যার এবং এটি চালানো সম্পূর্ণ বৈধ। গুরুত্বপূর্ণ বিষয় হলো কন্টেন্ট: শুধুমাত্র আপনার মালিকানাধীন বা লাইসেন্সকৃত মিডিয়া, যেমন আপনার নিজের ডিস্ক রিপ, রেকর্ডিং বা যে ফাইলগুলো রাখার অধিকার আপনার আছে, সেগুলো স্ট্রিম করুন। Jellyfin কোনো মিডিয়া সরবরাহ করে না এবং কোনো মিডিয়া পাওয়ার উপায়ও দেয় না; এটি শুধুমাত্র আপনার মালিকানাধীন লাইব্রেরির একটি প্লেয়ার।