Jellyfin
I completely love jellyfin. Plex has always been a scam waiting to happen in my eyes. Jellyfin requires some love to work across a lot of devices, but for that I have AI. I also have AI for the writeup below.
Why Jellyfin?
Completely Free: No premium tiers, all features available to everyone
Open Source: Transparent code, community-driven development
No Tracking: Your viewing habits stay private
Hardware Transcoding: Supports GPU acceleration for efficient streaming
Cross-Platform: Apps for web, mobile, TV, and desktop
Features
Media Management
- Automatic metadata fetching (posters, descriptions, cast info)
- Library organization by type (Movies, TV, Music)
- Collection and playlist support
- Watched status tracking across devices
Streaming
- Adaptive bitrate streaming
- Hardware-accelerated transcoding
- Direct play when possible (no transcoding)
- Multiple audio/subtitle track support
- Resume playback across devices
User Management
- Multiple user accounts
- Per-user watch history and preferences
- Parental controls and content restrictions
- Shared or separate libraries per user
Clients
- Web browser (any device)
- Android and iOS apps
- Android TV, Apple TV, Roku, Fire TV
- Desktop apps (Windows, Mac, Linux)
- Kodi plugin
Installation with Docker
Basic Setup
Create docker-compose.yml:
version: '3.8'
services:
jellyfin:
image: jellyfin/jellyfin:latest
container_name: jellyfin
ports:
- "8096:8096"
volumes:
- jellyfin-config:/config
- jellyfin-cache:/cache
- /path/to/movies:/media/movies:ro
- /path/to/tv:/media/tv:ro
- /path/to/music:/media/music:ro
restart: unless-stopped
environment:
- TZ=America/Chicago
volumes:
jellyfin-config:
jellyfin-cache:
Start the service:
docker compose up -d
Access at: http://your-server:8096
With Hardware Transcoding
Intel QuickSync:
services:
jellyfin:
# ... other config ...
devices:
- /dev/dri:/dev/dri
group_add:
- "109" # render group
NVIDIA GPU:
services:
jellyfin:
# ... other config ...
runtime: nvidia
environment:
- NVIDIA_VISIBLE_DEVICES=all
- NVIDIA_DRIVER_CAPABILITIES=all
AMD GPU:
services:
jellyfin:
# ... other config ...
devices:
- /dev/dri:/dev/dri
group_add:
- "109" # render group or video group
Initial Configuration
First-Time Setup
- Access Web Interface: Navigate to
http://your-server:8096 - Create Admin Account: Set username and password
- Add Media Libraries:
- Click "Add Media Library"
- Select type (Movies, TV Shows, Music)
- Point to media folder
- Configure metadata providers
- Scan Libraries: Let Jellyfin discover and organize your media
Library Organization
Recommended folder structure:
/media/
├── movies/
│ ├── Movie Title (2020)/
│ │ └── Movie Title (2020).mkv
│ └── Another Movie (2021)/
│ └── Another Movie (2021).mp4
├── tv/
│ └── TV Show Name/
│ ├── Season 01/
│ │ ├── S01E01.mkv
│ │ └── S01E02.mkv
│ └── Season 02/
│ └── S02E01.mkv
└── music/
└── Artist Name/
└── Album Name/
├── 01 - Track Name.mp3
└── 02 - Track Name.mp3
Transcoding Settings
Navigate to: Dashboard → Playback
Hardware Acceleration:
- Select your GPU type (Intel QSV, NVIDIA NVENC, AMD AMF, VA-API)
- Enable hardware encoding/decoding
- Test with a video to verify it works
Transcoding Quality:
- Set target bitrates for different resolutions
- Configure codec preferences (H.264, HEVC, AV1)
- Enable tone mapping for HDR content
Performance Optimization
Storage Considerations
Media Storage: Use HDDs for bulk storage (movies/TV)
- Sequential reads are fine for streaming
- 7200 RPM drives recommended
- RAID optional but not required
Config/Cache: Use SSD for Jellyfin config and cache
- Faster metadata loading
- Improved UI responsiveness
- Quicker library scans
Network Optimization
Direct Play: Best performance, no transcoding
- Use compatible formats (H.264/AAC in MP4/MKV)
- Ensure client supports the codec
- Requires sufficient bandwidth
Transcoding: When direct play isn't possible
- Uses CPU/GPU resources
- Reduces bandwidth requirements
- May introduce slight delay
Bandwidth Requirements:
- 1080p: 8-10 Mbps
- 4K: 25-40 Mbps
- Multiple streams: Multiply accordingly
Resource Usage
CPU: Minimal when direct playing, high when transcoding
RAM: 2-4GB typical, more with many users
GPU: Significantly reduces CPU load for transcoding
Storage I/O: Moderate, one stream ≈ 10-40 MB/s
Remote Access
Via Tailscale (Recommended)
- Install Tailscale on server and clients
- Access Jellyfin via Tailscale IP:
http://100.x.x.x:8096 - No port forwarding required
- Encrypted connection
Via Reverse Proxy
Use NGINX to add HTTPS and custom domain:
server {
listen 443 ssl http2;
server_name jellyfin.yourdomain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
client_max_body_size 0;
location / {
proxy_pass http://localhost:8096;
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_buffering off;
}
}
Mobile Apps
Android: Available on Google Play and F-Droid
iOS: Available on App Store
Features:
- Download media for offline viewing
- Cast to Chromecast/AirPlay
- Background audio playback
- Picture-in-picture support
Troubleshooting
Transcoding Not Working
Check GPU access:
# Verify GPU is available
ls -la /dev/dri
# Check container can access GPU
docker exec jellyfin ls -la /dev/dri
Check logs:
docker logs jellyfin | grep -i transcode
Playback Stuttering
Possible causes:
- Insufficient bandwidth
- Transcoding overload
- Disk I/O bottleneck
Solutions:
- Lower quality settings in client
- Enable hardware transcoding
- Move cache to SSD
- Limit concurrent streams
Metadata Not Loading
Solutions:
- Check internet connectivity
- Verify metadata providers are enabled
- Manually identify problematic items
- Rescan library
High CPU Usage
Causes:
- Active transcoding
- Library scanning
- Thumbnail generation
Solutions:
- Enable hardware transcoding
- Schedule scans during off-hours
- Limit concurrent streams
Maintenance
Updates
# Pull new image
docker compose pull
# Restart with new version
docker compose up -d
Backups
What to backup:
/configvolume (database, settings, metadata)- Docker compose file
What not to backup:
/cachevolume (can be regenerated)- Media files (backup separately if needed)
Library Maintenance
Regular tasks:
- Remove missing media from library
- Update metadata for new releases
- Clean up old cache files
- Review and fix misidentified items
Alternatives Comparison
| Feature | Jellyfin | Plex | Emby |
|---|---|---|---|
| Cost | Free | Freemium | Freemium |
| Open Source | Yes | No | No |
| Hardware Transcoding | Free | Plex Pass | Premiere |
| Mobile Sync | Free | Plex Pass | Premiere |
| User Management | Free | Free | Free |
| Live TV/DVR | Free | Free | Premiere |
Best Practices
Media Organization: Follow naming conventions for automatic metadata
Hardware Transcoding: Essential for multiple concurrent streams
Regular Updates: Keep Jellyfin updated for bug fixes and features
Backup Configuration: Regularly backup your config volume
Monitor Resources: Watch CPU/GPU usage during peak times
Test Clients: Verify playback works on all your devices
Related Topics:
- Self-Hosting a Home Server - Complete homelab guide
- Docker - Container platform
- Navidrome - Music streaming server
- Immich - Photo management