Reading time: ~14 minutes
Audience: Media enthusiasts leaving Plex or Emby due to policy changes or subscription fatigue
Last tested: Jellyfin 10.10, June 2026


What Is Jellyfin?

Overview

Jellyfin is a free, open-source media server forked from Emby before it went closed-source. It organizes your movies, TV shows, music, and photos into a Netflix-like interface, then streams them to browsers, mobile apps, smart TVs, and DLNA devices — all without calling home, collecting telemetry, or charging subscription fees.

Unlike Plex, Jellyfin does not require account creation, and your viewing habits are never sent to a third-party analytics platform.

Key Benefits

Feature Jellyfin Plex Emby
Cost 100% free Freemium (paid features) Freemium
Open source ✅ (GPLv2) Partial
Phone home / telemetry None Yes Yes
Hardware transcoding Free Paid (Plex Pass) Paid (Premiere)
Live TV / DVR Free Paid Paid
Plugins 30+ community Curated store Curated store

Prerequisites

Hardware Requirements

Use Case CPU RAM Storage GPU
Direct play only (no transcode) Any 2-core 2 GB 1 TB+ HDD None
2–3 concurrent 1080p transcodes 4-core modern 4 GB 1 TB SSD for metadata Intel UHD / Iris Xe
4+ concurrent 4K HDR → 1080p 6-core 8 GB 256 GB SSD cache + NAS Intel Arc, NVIDIA GTX 1650+

Transcoding Quick Reference

Direct Play: The client plays the file as-is. Zero CPU/GPU usage. Best quality.

Transcoding: The server re-encodes the video in real time for incompatible clients (old phones, bandwidth-limited remotes). This is where hardware acceleration matters.

Codec Direct Play Support Often Needs Transcode
H.264 (AVC) Universal Rare
H.265 (HEVC) Modern devices Older Roku, web browsers
AV1 2022+ devices Almost everything else
4K HDR → 1080p SDR Never direct Always (tone mapping)

Step 1: Deploy Jellyfin with Docker Compose

Objective

Create a Compose file with proper volume mappings for media, config, and hardware device access.

Step-by-Step Instructions

  1. Create a project directory:
mkdir -p ~/jellyfin/{config,cache,media} && cd ~/jellyfin
  1. Set correct permissions (Jellyfin runs as UID/GID 1000:1000 by default):
chown -R 1000:1000 config cache
  1. Create docker-compose.yml:
version: "3.8"

services:
  jellyfin:
    image: jellyfin/jellyfin:10.10
    container_name: jellyfin
    restart: unless-stopped
    user: 1000:1000
    group_add:
      - "105"  # Change to your host's render group ID for GPU access
    network_mode: host  # Simplifies DLNA and client discovery
    volumes:
      - ./config:/config
      - ./cache:/cache
      - /mnt/media:/media:ro  # Read-only access to your media library
    environment:
      - JELLYFIN_PublishedServerUrl=http://jellyfin.lan
    # Uncomment the appropriate device block for GPU transcoding:
    # Intel Quick Sync:
    # devices:
    #   - /dev/dri:/dev/dri
    # NVIDIA:
    # deploy:
    #   resources:
    #     reservations:
    #       devices:
    #         - driver: nvidia
    #           count: 1
    #           capabilities: [gpu]
  1. Find your render group ID (for Intel/AMD GPU passthrough):
getent group render | cut -d: -f3

Replace 105 in group_add with your actual value.

  1. Start Jellyfin:
docker compose up -d
  1. Access the web UI:
http://your-server-ip:8096

Step 2: Initial Library Setup

Objective

Add media folders and let Jellyfin scan your collection.

Step-by-Step Instructions

  1. On first launch, Jellyfin walks you through setup:
  2. Preferred display language: Choose your language
  3. Username / Password: Create the admin account
  4. Add Media Library:

    • Content type: Movies, TV Shows, Music, etc.
    • Display name: e.g., “Movies”, “TV Shows”
    • Folders: /media/movies, /media/tv, etc.
    • Preferred language: English (or your language)
    • Metadata downloaders: Enable TheMovieDB, TheTVDB, OMDB
    • Image fetchers: Enable TheMovieDB, Screen Grabber
  5. Click Next → Next → Finish.

  6. Jellyfin will begin scanning. For 1,000 movies, this takes 15–30 minutes depending on internet speed and CPU.

Recommended folder structure:

/mnt/media/
├── movies/
│   ├── The Matrix (1999)/
│   │   └── The Matrix (1999) [1080p].mkv
│   └── Inception (2010)/
│       └── Inception (2010) [2160p].mkv
├── tv/
│   ├── Breaking Bad/
│   │   ├── Season 01/
│   │   │   ├── Breaking Bad - S01E01.mkv
│   │   │   └── Breaking Bad - S01E02.mkv
└── music/
    ├── Artist Name/
    │   ├── Album Name/
    │   │   └── 01 - Track Name.flac

Pro Tip: Name files accurately. Jellyfin matches using Movie Name (Year) and Series Name - SXXEYY patterns. Tools like Sonarr and Radarr automate naming.


Step 3: Enable Hardware Transcoding

Objective

Offload video transcoding from CPU to GPU for smooth 4K→1080p conversions.

Step-by-Step Instructions

For Intel Quick Sync (12th–14th Gen, N100–N305):

  1. Ensure /dev/dri is passed through in docker-compose.yml:
    devices:
      - /dev/dri:/dev/dri
  1. In Jellyfin web UI: Administration → Playback → Transcoding
  2. Enable hardware decoding: ✅
  3. Hardware acceleration: Intel QuickSync (QSV)
  4. Enable hardware encoding: ✅
  5. Allow decoding: Check all formats (H264, HEVC, VP9, AV1)

  6. Click Save.

  7. Test by playing a 4K file on a remote device and checking the dashboard for the orange ✅ “Transcoding” indicator. CPU usage should drop to <10%.

For NVIDIA GPUs:

  1. Install the NVIDIA Container Toolkit on the host:
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt update && sudo apt install -y nvidia-docker2
sudo systemctl restart docker
  1. Use the deploy block in Compose (shown in Step 1).
  2. In Jellyfin, select NVIDIA NVENC as the acceleration method.

Step 4: Remote Access and HTTPS

Objective

Stream securely from outside your home network.

Step-by-Step Instructions

Option A: Reverse Proxy (Recommended)

Add a Proxy Host in NGINX Proxy Manager: | Field | Value | |———-|———-| | Domain | jellyfin.yourdomain.com | | Forward Host | your-server-ip | | Forward Port | 8096 | | Block Exploits | ✅ | | Websockets | ✅ |

In Jellyfin: Administration → Networking: - Base URL: leave blank - Public HTTPS port: 443 - Known proxies: Add your reverse proxy IP or subnet

Option B: Tailscale / Zero Trust

Install Tailscale on your Jellyfin host and client devices. Access Jellyfin at http://jellyfin-host:8096 over the encrypted mesh network without opening firewall ports.

Option C: Direct Port Forward (Not Recommended)

Forward router port 8096 to your Jellyfin host. Only use this with Jellyfin’s built-in HTTPS and strong passwords.


Pro Tips

Tip 1: Use Sonarr + Radarr + Bazarr for Automation

  • Sonarr: TV show downloading and renaming
  • Radarr: Movie downloading and renaming
  • Bazarr: Subtitle downloading
  • Prowlarr: Indexer management

Run them all in a separate Docker Compose stack and point their root folders to /mnt/media.

Tip 2: Enable Tone Mapping for HDR Content

Without tone mapping, HDR movies look washed out on SDR screens: - Administration → Playback → Tone mapping: Enable - Tone mapping algorithm: BT.2390 (best quality) or Reinhard (lower GPU load) - Tone mapping mode: GPU if you have hardware acceleration

Tip 3: Cache Metadata on SSD

If your media lives on a slow NAS or HDD, keep Jellyfin’s config and cache on an SSD. Our Compose file already does this via ./config and ./cache bind mounts.

Tip 4: Limit Transcode Sessions

Prevent a single remote user from monopolizing your GPU: - Administration → Playback → Transcoding → Max transcode sessions: 2


Troubleshooting Common Issues

No compatible streams” Error

  • The client cannot direct play the file and transcoding is failing.
  • Check that hardware acceleration is enabled and /dev/dri is visible inside the container: bash docker exec -it jellyfin ls -la /dev/dri
  • If empty, your group_add or devices block is incorrect.

Slow Library Scanning

  • Disable real-time monitoring if using network storage (NFS/SMB): Administration → Libraries → [Library] → Advanced → Enable real time monitoring: ❌
  • Schedule a nightly scan instead: Administration → Scheduled Tasks → Scan Media Library

Subtitles Not Showing

  • Ensure the subtitle file has the same base name as the video: Movie (2024).mkvMovie (2024).en.srt
  • Or use Bazarr to fetch subtitles automatically.

Conclusion

Summary

You now have Jellyfin running in Docker with hardware transcoding, a properly organized media library, and secure remote access. It replaces Plex or Emby without subscription fees or telemetry.

Next Steps


Affiliate Opportunities

  • Storage: WD Red Plus or Seagate IronWolf NAS drives for media libraries
  • Mini PCs: Beelink SER6 (AMD Radeon 680M) for excellent GPU transcoding
  • Networking: 2.5 GbE switches for local 4K direct play without buffering

Internal Linking Strategy

  • what-is/jellyfin-vs-plex-vs-emby for readers weighing options
  • hardware/low-power-homelab-server-build for hardware recommendations
  • conclusion/sonarr-radarr-docker-compose for media automation

CTA

What are you streaming on Jellyfin? Share your library size and favorite client in the comments!

Subscribe to the WordForge newsletter for weekly self-hosted media and homelab guides.