Skip to content

Jellyfin Media Server

Jellyfin is the self-hosted media streaming platform powering the homelab's entertainment system. As an open-source alternative to Plex, it provides complete control over media without subscriptions, telemetry, or feature paywalls.

Overview

What is Jellyfin? A free, open-source media server that organizes, manages, and streams movies, TV shows, music, and photos to any device.

Why Jellyfin over Plex? - Completely free and open source - No premium features locked behind paywall - No phone-home telemetry or tracking - Active community development - Docker-friendly deployment

Features

Media Management

  • Automatic Metadata – Fetches posters, descriptions, ratings from TMDB/TVDB
  • Library Organization – Separate libraries for movies, TV, music, photos
  • Collections – Group related content (Marvel movies, Star Wars, etc.)
  • Watched Status – Track progress across all users

Streaming Capabilities

  • Adaptive Streaming – Adjusts quality based on bandwidth
  • Hardware Transcoding – Intel QuickSync, NVIDIA, AMD GPU support
  • Direct Play – Stream without transcoding when client supports format
  • Remote Access – Secure streaming from anywhere
  • Offline Downloads – Mobile apps support offline sync

User Management

  • Multi-User Support – Separate profiles with individual watch history
  • Parental Controls – Content ratings and library restrictions
  • Guest Access – Temporary accounts for visitors
  • SSO Integration – LDAP/Active Directory authentication

Client Apps

  • Web Browser – Full-featured web interface
  • Mobile Apps – iOS and Android (Jellyfin, Swiftfin, Finamp)
  • TV Apps – Android TV, Apple TV, Roku, Fire TV
  • Desktop Apps – Windows, macOS, Linux clients
  • Third-Party – Kodi, Infuse, MPV Shim

Installation

Docker Compose

version: '3.8'

services:
  jellyfin:
    image: jellyfin/jellyfin:latest
    container_name: jellyfin
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/Chicago
    volumes:
      - /opt/stacks/jellyfin/config:/config
      - /opt/stacks/jellyfin/cache:/cache
      - /mnt/media/movies:/data/movies:ro
      - /mnt/media/tv:/data/tv:ro
      - /mnt/media/music:/data/music:ro
    ports:
      - "8096:8096"
      - "8920:8920"  # HTTPS
      - "7359:7359/udp"  # Auto-discovery
    devices:
      - /dev/dri:/dev/dri  # Hardware transcoding (Intel QuickSync)
    networks:
      - proxy
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.jellyfin.rule=Host(`jellyfin.local`)"
      - "traefik.http.services.jellyfin.loadbalancer.server.port=8096"
    restart: unless-stopped

networks:
  proxy:
    external: true

Hardware Transcoding Setup

devices:
  - /dev/dri:/dev/dri

# Add user to render group on host
sudo usermod -aG render jellyfin

NVIDIA GPU

runtime: nvidia
environment:
  - NVIDIA_VISIBLE_DEVICES=all
  - NVIDIA_DRIVER_CAPABILITIES=all

Configuration

Library Setup

Movies

Path: /data/movies
Content Type: Movies
Metadata Language: English
Country: United States
Metadata Downloaders: TheMovieDb
Image Fetchers: TheMovieDb

TV Shows

Path: /data/tv
Content Type: Shows
Episode Naming: {Series Name} - S{season:00}E{episode:00} - {Episode Name}
Metadata Downloaders: TheTVDB
Season Images: TheMovieDb, TheTVDB

Transcoding Settings

Playback Settings: - Hardware Acceleration: Intel QuickSync (QSV) - Enable hardware encoding - Preferred codec: H.264 - Max streaming bitrate: Auto (or set per user)

Transcoding Settings: - Transcoding temp path: /cache/transcodes - Delete after playback: Enabled - Throttle transcoding: Enabled

User Configuration

Default User Settings: - Enable downloads: No - Max streaming quality: 1080p - Subtitle mode: Default - Intro detection: Enabled

Admin Account: - Full library access - User management - Plugin installation - Server settings

Integration with *arr Stack

Radarr/Sonarr Connection

Jellyfin automatically detects new media added by Radarr/Sonarr:

  1. *arr app downloads and organizes media
  2. Files placed in /data/movies or /data/tv
  3. Jellyfin monitors folders for changes
  4. Metadata automatically fetched
  5. Content appears in library

Library Scan Settings

Real-time monitoring: Enabled
Scan interval: 30 minutes
Ignore pattern: *.tmp, *.part

Plugins

Essential Plugins

Playback Reporting - Track all playback activity - Export to Jellystat - User statistics

Intro Skipper - Auto-detect TV show intros - One-click skip button - Credits detection

Trakt - Sync watch history to Trakt.tv - Scrobble playback - Recommendations

LDAP Authentication - Connect to Active Directory - Centralized user management - SSO integration

Plugin Installation

Dashboard → Plugins → Catalog → Install
Restart Jellyfin after installation

Performance Optimization

Hardware Transcoding

Enable QuickSync for 10-15x faster transcoding:

Dashboard → Playback → Hardware Acceleration
Select: Intel QuickSync (QSV)
Enable all encoding options

Pre-Transcoding

Convert media to efficient formats ahead of time:

# Batch convert with ffmpeg
for file in *.mkv; do
  ffmpeg -i "$file" \
    -c:v libx264 -preset slow -crf 20 \
    -c:a aac -b:a 192k \
    "${file%.mkv}.mp4"
done

Caching

  • Use SSD for cache directory
  • Set transcoding temp to fast storage
  • Enable image caching

Remote Access

Traefik Reverse Proxy

labels:
  - "traefik.http.routers.jellyfin-secure.rule=Host(`jellyfin.example.com`)"
  - "traefik.http.routers.jellyfin-secure.entrypoints=https"
  - "traefik.http.routers.jellyfin-secure.tls=true"
  - "traefik.http.routers.jellyfin-secure.middlewares=authelia@docker"

Client Connection

Users connect via: - Local: http://jellyfin.local:8096 - Remote: https://jellyfin.example.com

Monitoring

Built-in Dashboard

  • Active streams
  • Transcoding sessions
  • CPU/memory usage
  • Playback errors

External Monitoring

  • Jellystat – Advanced analytics and viewing trends
  • Checkmk – System resource monitoring
  • Graylog – Log aggregation for errors/warnings

Alerts

Set up alerts for: - Transcoding failures - High resource usage - Authentication failures - Storage capacity warnings

Backup & Recovery

What to Backup

/opt/stacks/jellyfin/config/     # Settings and database
/opt/stacks/jellyfin/config/data/library.db  # Watch history

Backup Script

#!/bin/bash
# Backup Jellyfin config
tar -czf jellyfin-backup-$(date +%Y%m%d).tar.gz \
  /opt/stacks/jellyfin/config/

# Copy to backup location
rsync -av jellyfin-backup-*.tar.gz /mnt/backup/jellyfin/

Restore Process

  1. Stop Jellyfin container
  2. Extract backup to config directory
  3. Restart container
  4. Verify libraries and users

Troubleshooting

Common Issues

Transcoding Fails

# Check hardware device permissions
ls -l /dev/dri/
# Verify QuickSync enabled in dashboard
# Check logs for codec errors
docker logs jellyfin | grep transcode

Metadata Not Loading

# Refresh metadata manually
Dashboard  Libraries  [Library]  Scan Library
# Check internet connectivity
# Verify TMDB/TVDB API access

Buffering During Playback - Check network bandwidth - Lower streaming quality - Enable hardware transcoding - Move cache to faster storage

Log Locations

# Container logs
docker logs jellyfin -f

# Jellyfin logs
/opt/stacks/jellyfin/config/log/

Best Practices

  1. Organize Media – Use proper naming conventions for Radarr/Sonarr
  2. Hardware Acceleration – Enable QuickSync/NVIDIA for transcoding
  3. User Limits – Set streaming quality limits for remote users
  4. Regular Backups – Backup config and database weekly
  5. Update Safely – Test updates in staging environment first
  6. Monitor Storage – Watch disk usage and set retention policies
  7. Secure Access – Use HTTPS and strong passwords
  8. Intro Detection – Enable intro skipper for better UX

Resources