SSD Nodes Learn Hosting plans →
নির্দেশিকা Matt Connorদ্বারা Matt Connor

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-তে চলে এবং সফটওয়্যার এনকোডিং বেশ ব্যয়বহুল। একটি মাত্র 1080p H.264 ট্রান্সকোড বেশ কয়েকটি শেয়ারড vCPU-কে ব্যস্ত করে ফেলতে পারে; একটি 4K বা HEVC ট্রান্সকোড সাধারণত রিয়েল-টাইমে চলতে পারে না, ফলে প্লেব্যাক আটকে যায় এবং বাফারিং চলতেই থাকে। হার্ডওয়্যার ট্রান্সকোডিং, যা Intel iGPU বা Nvidia কার্ডযুক্ত হোম বক্সে এই কাজটিকে সহজ করে তোলে, তা আপনার জন্য সহজলভ্য নয় যদি না আপনার প্রোভাইডার GPU ইনস্ট্যান্স ভাড়া দেয়।

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

ব্যান্ডউইথের হিসাবটিও করে নিন, কারণ এটি আরেকটি চমক হতে পারে। Direct play ফাইলটিকে তার নিজস্ব বিটরেটে পাঠায়। একটি কম্প্রেসড 1080p ফাইল 8-12 Mbps গতিতে চলে; একটি 1080p Blu-ray রিমাক্স 20-30 Mbps; 4K HDR 40-80 Mbps। তিনজন মানুষ যদি 10 Mbps-এর ফাইল সরাসরি প্লে করে, তবে আপনার VPS থেকে 30 Mbps আপলোড ব্যান্ডউইথ প্রয়োজন হবে। আপনার প্ল্যানের দুটি সংখ্যা যাচাই করুন: পোর্ট স্পিড (এটি কি 30 Mbps আপস্ট্রিম দিতে পারে?) এবং মাসিক ট্রান্সফার ক্যাপ। দুই ঘণ্টার একটি 10 Mbps মুভি প্রায় 9 GB ডেটা খরচ করে, তাই 1 TB/মাস লিমিট থাকলে মাসে এমন প্রায় একশটি মুভি দেখা সম্ভব, অর্থাৎ দিনে তিন বা চারটি। আর 4K ভিডিও দেখলে, যা চার থেকে আট গুণ বেশি বিটরেট ব্যবহার করে, তা অনেক দ্রুত লিমিট শেষ করে দেবে। একই বক্সে অন্য কোনো ট্রাফিক থাকলে তাও এই বাজেটের মধ্যে হিসাব করুন, যার মধ্যে a self-hosted RustDesk relay-ও অন্তর্ভুক্ত, যা দুটি পিয়ার সরাসরি কানেক্ট হতে না পারলে পুরো রিমোট ডেস্কটপ সেশন বহন করে।

পূর্বশর্ত

  • 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) (Jellyfin-এর জন্য বছরটি ঐচ্ছিক, তবে এটি থাকলে ম্যাচিং অনেক বেশি নির্ভুল হয়); সিজন ফোল্ডারগুলোর নাম হতে হবে Season 01, S01 নয়; এপিসোড ফাইলের ক্ষেত্রে S01E01 ব্যবহার করুন; এবং স্পেশাল এপিসোডগুলো 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:12
    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

লাইন অনুযায়ী ব্যাখ্যা: jellyfin/jellyfin:12 বর্তমান 12.x রিলিজ লাইন ট্র্যাক করে (2026-10-10 অনুযায়ী এটি 12.2)। user: "1000:1000" সেই uid/gid সেট করে যা দিয়ে Jellyfin প্রসেসটি চলে। এটি কোনো ফাইলের মালিকানা বা মোড পরিবর্তন করে না, কারণ Docker মাউন্ট করা ডিরেক্টরিগুলোতে হোস্টের uid/gid বজায় রাখে, আর এই কারণেই উপরের chown-এর সাথে এটি মিল থাকা প্রয়োজন। /config পুরো সার্ভার, অ্যাকাউন্ট, লাইব্রেরি, মেটাডেটা এবং দেখার অবস্থা (watch state) ধারণ করে, তাই এটি অবশ্যই রাইট-এবল (writable) হতে হবে এবং এটিই সেই অংশ যা আপনাকে ব্যাকআপ রাখতে হবে। /cache হলো অস্থায়ী কাজের জায়গা। মিডিয়া মাউন্টটি ইচ্ছাকৃতভাবেই :ro (read-only) রাখা হয়েছে: Jellyfin ডিফল্টভাবে আর্টওয়ার্ক এবং মেটাডেটা /config-এর অধীনে সংরক্ষণ করে, তাই আপনার লাইব্রেরিতে এর কখনোই লেখার প্রয়োজন পড়ে না এবং read-only মোড আপনার ফাইলগুলোকে ভুলবশত মুছে ফেলা বা কোনো ত্রুটিপূর্ণ প্লাগইন থেকে রক্ষা করে। পোর্টটি ইচ্ছাকৃতভাবে 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 ব্যবহার করে জোরপূর্বক পুনরায় স্ক্যান করতে পারবেন। প্রাথমিক কাজগুলো সম্পন্ন হলে বিকল্প ফ্রন্টএন্ডগুলো ব্যবহার করে দেখতে পারেন, কারণ Halcyon Jellyfin-এর সংগ্রহ করা আর্টওয়ার্ক ব্যবহার করে নব্বইয়ের দশকের ভিডিও স্টোরের মতো একটি ইন্টারফেস তৈরি করে।

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

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

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

অপশন A, TLS রিভার্স প্রক্সি। Jellyfin-কে একটি সাবডোমেইনের অধীনে রাখুন, যা Traefik with automatic TLS for your Docker apps-এর পেছনে অথবা nginx-এর পেছনে থাকবে, যেখানে Let's Encrypt certificate issued by Certbot ব্যবহার করা হয়েছে। 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-এর দিকে নির্দেশ করুন যাতে আপনার ব্যবহারকারীদের আগেই আপনি ডাউনটাইম সম্পর্কে জানতে পারেন। এর নোটিফিকেশনগুলো a self-hosted ntfy server-এ পাঠান, যাতে কোনো চেক ব্যর্থ হলে তা ইমেইলের পরিবর্তে সরাসরি ফোনে পুশ নোটিফিকেশন হিসেবে আসে। পাবলিক ইন্টারনেটে লগইন উন্মুক্ত করার সময় এটি সার্ভারের অন্যান্য অংশ অডিট করারও একটি ভালো সুযোগ, শুধুমাত্র 443 পোর্ট খোলা আছে কি না তা বিশ্বাস না করে: sudo ss -tlnp প্রতিটি লিসেনিং পোর্ট এবং তার পেছনের প্রসেসগুলোর তালিকা দেখায়। আপনি যদি সার্ভারে নিজের কোডও ডিপ্লয় করেন, তবে open-kritt scans repositories and their dependencies for vulnerabilities ব্যবহার করুন; এটি সোর্স কোড অডিট করে, লিসেনিং পোর্ট নয়।

অপশন B, VPN-এর মাধ্যমে ব্যক্তিগত রাখা। 8096 পোর্টটি পাবলিক ইন্টারনেটে একেবারেই উন্মুক্ত করবেন না; Jellyfin-কে শুধুমাত্র একই বক্সে টার্মিনেট হওয়া WireGuard টানেলের মাধ্যমে অ্যাক্সেস করুন। একটি পরিবারের জন্য এটি সবচেয়ে সহজ ও নিরাপদ উপায়, এতে কোনো সার্টিফিকেটের প্রয়োজন নেই, পাবলিক এক্সপোজার নেই এবং ব্রুট-ফোর্স আক্রমণের ঝুঁকি নেই। কম্পোজ ফাইল থেকে লোকালহোস্ট বাইন্ডিং এখানে যথেষ্ট নয়, কারণ 127.0.0.1-এ প্রকাশিত পোর্ট শুধুমাত্র VPS থেকেই অ্যাক্সেসযোগ্য, VPN পিয়ার থেকে নয়। এটিকে সার্ভারের টানেল ঠিকানায় প্রকাশ করুন (উদাহরণস্বরূপ "10.8.0.1:8096:8096", আপনার নিজস্ব WireGuard সার্ভার IP ব্যবহার করে), অথবা লোকালহোস্ট রেখে তার সামনে টানেল ঠিকানায় লিসেনিং একটি প্রক্সি বসান এবং তারপর 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 হলো পুরো সার্ভারের স্টেট, তাই এটিই একমাত্র জিনিস যা আপনাকে অবশ্যই ব্যাকআপ রাখতে হবে। স্ন্যাপশট নিন অথবা সার্ভার বন্ধ করে tar কমান্ডের মাধ্যমে ব্যাকআপ তৈরি করুন এবং সেই কপিটি সার্ভারের বাইরে সংরক্ষণ করুন:

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

/cache এবং ট্রান্সকোড ফোল্ডারটি মুছে ফেলা যায়। /mnt/media-এ থাকা মিডিয়া ফাইলগুলো আপনি আলাদাভাবে ব্যাকআপ রাখতে পারেন অথবা এগুলো পুনরায় সংগ্রহ করা যাবে ধরে নিতে পারেন; ফাইলের সাইজ অনেক বড় হওয়ায় বেশিরভাগ মানুষ দ্বিতীয় পদ্ধতিটিই বেছে নেন। আপগ্রেড করার প্রক্রিয়াটি docker compose pull && docker compose up -d; উপরের :12 ট্যাগটি 12.x লাইনের মধ্যেই সীমাবদ্ধ থাকে, তাই পরবর্তী মেজর ভার্সনে যাওয়ার জন্য আপনাকে সচেতনভাবে ট্যাগ পরিবর্তন করতে হবে। পরিবর্তন করার আগে Jellyfin রিলিজ নোটগুলো দেখে নিন, কারণ মেজর ভার্সনগুলোতে লাইব্রেরি স্কিমা মাইগ্রেশন হয়ে থাকে। Jellyfin 12.0 (সেপ্টেম্বর 2026) ভার্সন থেকে তাদের ভার্সন নম্বর থেকে শুরুর "10." বাদ দিয়েছে: 12.0 হলো সেটি যা 10.12 হওয়ার কথা ছিল, এখানে কোনো 11.x ভার্সন নেই এবং 10.11.x ছিল পুরনো স্কিমের শেষ লাইন। যদি আপনার পুরনো compose ফাইলে এখনো jellyfin/jellyfin:10 লেখা থাকে, তবে এটি 10.11 ভার্সনেই আটকে আছে (এই ট্যাগটি সর্বশেষ 2026-06-06 তারিখে 10.11.11-এ আপডেট হয়েছিল) এবং এটি কখনোই 12.x ভার্সন পুল করবে না। এটিকে :12-এ পরিবর্তন করা কেবল একটি ট্যাগ পরিবর্তনের চেয়ে বেশি কিছু: 12.0 ভার্সনে ডাটাবেস স্কিমা পরিবর্তিত হয় এবং প্রথমবার বুট করার সময় ডাটা নতুন করে লেখা হয়। তাই সার্ভার বন্ধ করে আগে উপরের ব্যাকআপটি নিয়ে নিন, কারণ সেই ব্যাকআপটিই ফিরে আসার একমাত্র উপায়। 12.0 ভার্সনে সরাসরি 10.10.7 বা যেকোনো 10.11.x রিলিজ থেকে আপগ্রেড করা যায় এবং এর পরে একটি পূর্ণাঙ্গ লাইব্রেরি স্ক্যান প্রয়োজন হয়, যা স্বাভাবিকের চেয়ে বেশ সময়সাপেক্ষ। একটি পিন করা ট্যাগ এবং একটি ব্যাকআপ করা স্টেট ডিরেক্টরি হলো যেকোনো অলওয়েজ-অন কন্টেইনারের মূল ভিত্তি, এবং এটিই রিবুটের পরেও সেলফ-হোস্টেড এজেন্টের মেমোরি এবং শিডিউল সচল রাখার পেছনের মূল কৌশল।

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

স্ক্যান করার পর লাইব্রেরি খালি দেখাচ্ছে। 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-ট্রান্সকোডিং করছে এবং ব্যর্থ হচ্ছে। কারণ: অসমর্থিত কোডেক (codec) বা কন্টেইনার, সাবটাইটেল বার্ন-ইন (burn-in), অথবা HDR টোন-ম্যাপিং। সমাধান: সরাসরি প্লে করতে পারে এমন ক্লায়েন্টে সুইচ করুন, সোর্স ফাইলগুলোকে H.264/AAC ফরম্যাটে রাখুন, image সাবটাইটেল (PGS/VOBSUB)-এর পরিবর্তে text সাবটাইটেল (SRT) ব্যবহার করুন (যেহেতু বেশিরভাগ Jellyfin ক্লায়েন্ট এগুলো নিজে থেকে দেখাতে পারে না এবং বার্ন-ইন করতে বাধ্য হয়), এবং 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 লাইনটি পড়ুন, ফাইলটি আদৌ চলে কি না তা নিশ্চিত করুন, ট্রান্সকোডিংয়ের ওপর নির্ভরশীল হলে ব্যবহারকারীর প্লেব্যাক অনুমতি পরীক্ষা করুন এবং ব্রাউজারের কোডেক সংক্রান্ত সমস্যা এড়াতে অন্য একটি ক্লায়েন্ট ব্যবহার করে দেখুন।

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