This article contains affiliate links. If you purchase through our links, we may earn a commission at no extra cost to you. We only recommend products we’ve thoroughly researched and verified.

Jellyfin is the free, open-source alternative to Plex. Hardware transcoding is free — no subscription, no account required. This guide walks through deploying Jellyfin on a mini PC via Docker, configuring hardware acceleration with VA-API, and setting up your media library for reliable 4K streaming.
What you need:
- A mini PC running Ubuntu Server 24.04 LTS with Docker installed
- Media files on local or external storage
Recommended hardware:
- Beelink EQ14 N150, VA-API — See current alternatives
- GEEKOM IT12 i5-12450H, Quick Sync — Check Price →
Step 1: Prepare the Host
Install VA-API Drivers Intel N150 / i5-12450H
# Install Intel VA-API drivers
sudo apt update
sudo apt install -y \
intel-media-va-driver-non-free \
vainfo \
i965-va-driver
# Verify GPU decoding is working
vainfo
Confirm the output lists H264, HEVC/H265, VP9, and ideally AV1 in the supported profiles.
For AMD iGPU Beelink SER9, Radeon 780M
# AMD VA-API via Mesa
sudo apt install -y mesa-va-drivers vainfo
# Test with AMD driver
LIBVA_DRIVER_NAME=radeonsi vainfo
Set Permissions for GPU Device
Add your user to the video and render groups so Docker containers can access /dev/dri:
sudo usermod -aG video $USER
sudo usermod -aG render $USER
newgrp render
Step 2: Deploy Jellyfin via Docker Compose
Create the directory structure:
mkdir -p ~/jellyfin/{config,cache}
mkdir -p /mnt/media/{movies,tvshows,music}
Mount external storage if needed:
# Find drive UUID
sudo blkid
# Add to /etc/fstab
UUID=your-drive-uuid /mnt/media ext4 defaults 0 2
# Mount
sudo mount -a
Create the Docker Compose file:
mkdir -p ~/jellyfin && nano ~/jellyfin/docker-compose.yml
services:
jellyfin:
image: jellyfin/jellyfin:latest
container_name: jellyfin
user: "1000:1000"
group_add:
- "44" # video group
- "109" # render group (check: getent group render)
ports:
- "8096:8096" # HTTP
- "8920:8920" # HTTPS
- "7359:7359/udp" # Local network discovery
volumes:
- ~/jellyfin/config:/config
- ~/jellyfin/cache:/cache
- /mnt/media:/media:ro # Media (read-only from Jellyfin)
devices:
- /dev/dri:/dev/dri # Hardware transcoding
environment:
- TZ=America/New_York
- JELLYFIN_PublishedServerUrl=http://192.168.1.100 # Your server IP
restart: unless-stopped
Start Jellyfin:
cd ~/jellyfin
docker compose up -d
# Watch startup logs
docker compose logs -f jellyfin
Access Jellyfin at http://192.168.1.100:8096
Step 3: Initial Setup Wizard
- Language selection → English
- Create account → Set admin username and password
- Setup media library:
- Click “Add Media Library”
- Content type: Movies
- Folder:
/media/movies - Repeat for TV Shows:
/media/tvshows
- Configure metadata language → English
- Allow remote connections → Yes
Jellyfin scans your library immediately after setup. Large libraries take minutes to hours for initial metadata scraping.
Step 4: Enable Hardware Transcoding
Navigate to Admin Dashboard → Playback → Transcoding:
- Hardware acceleration: Select “Intel QuickSync Video” for Intel iGPU or “Video Acceleration API VAAPI” works for both Intel and AMD
- VA-API Device:
/dev/dri/renderD128 - Enable hardware decoding for:
- H264 ✓
- HEVC H265 ✓
- VP8 ✓
- VP9 ✓
- AV1 ✓ if supported by your iGPU
- Enable hardware encoding: ✓
- Allow hardware transcoding fallback: ✓
Save settings.
Verify hardware transcoding is active:
Start playing a video that requires transcoding. In Admin Dashboard → Dashboard → Active Streams — the session should show the codec with “Direct” or ” hw” label rather than ” sw”.
Step 5: Organize Your Media Library
Jellyfin uses The Movie Database TMDB and TheTVDB for metadata. Proper file naming ensures correct matching.
Movies
/media/movies/
├── The Dark Knight (2008)/
│ └── The Dark Knight (2008).mkv
├── Interstellar (2014)/
│ └── Interstellar (2014).mkv
├── Dune Part Two (2024)/
│ └── Dune Part Two (2024).mkv
TV Shows
/media/tvshows/
├── The Expanse/
│ ├── Season 01/
│ │ ├── The Expanse S01E01.mkv
│ │ └── The Expanse S01E02.mkv
│ ├── Season 02/
Automated Library Organization
Use Radarr for movie management and Sonarr for TV shows — both integrate directly with Jellyfin and manage naming automatically.
Step 6: Configure Remote Access
Using Nginx Proxy Manager Recommended
Deploy Nginx Proxy Manager alongside Jellyfin:
# Add to docker-compose.yml
nginx-proxy-manager:
image: jc21/nginx-proxy-manager:latest
ports:
- "80:80"
- "443:443"
- "81:81" # Admin UI
volumes:
- ./npm/data:/data
- ./npm/letsencrypt:/etc/letsencrypt
restart: unless-stopped
In NPM admin port 81:
- Add Proxy Host → Domain:
jellyfin.yourdomain.com - Forward to:
jellyfin:8096 - Enable SSL → Request Let’s Encrypt certificate
- Enable WebSockets support
Direct Port Forwarding
Forward port 8096 TCP on your router to the mini PC’s IP. Optionally add HTTPS with a self-signed certificate or Let’s Encrypt via Certbot.
Step 7: Set Up Clients
Recommended Jellyfin Clients
| Platform | App | Notes |
|---|---|---|
| Apple TV | Jellyfin for tvOS | Good H.265 Direct Play |
| Android TV / Fire TV | Jellyfin for Android TV | Excellent client |
| Roku | Official Jellyfin channel | Available in Roku Channel Store |
| iOS / Android | Jellyfin Mobile | Free, full featured |
| Web browser | Any browser | Access via http://<ip>:8096 |
| Windows | Jellyfin Media Player | Desktop client |
For best performance: Configure clients to use Direct Play when possible — this sends the original file to the client without transcoding. Enable Direct Play in Jellyfin client settings → Streaming Quality → Maximum Quality.
Advanced: Jellyfin with *arr Stack
Jellyfin integrates with Radarr, Sonarr, and Prowlarr for automated media management:
# Full media stack docker-compose.yml
services:
jellyfin:
# ... as above
radarr:
image: lscr.io/linuxserver/radarr:latest
ports:
- "7878:7878"
volumes:
- ./radarr:/config
- /mnt/media/movies:/movies
restart: unless-stopped
sonarr:
image: lscr.io/linuxserver/sonarr:latest
ports:
- "8989:8989"
volumes:
- ./sonarr:/config
- /mnt/media/tvshows:/tv
restart: unless-stopped
prowlarr:
image: lscr.io/linuxserver/prowlarr:latest
ports:
- "9696:9696"
volumes:
- ./prowlarr:/config
restart: unless-stopped
qbittorrent:
image: lscr.io/linuxserver/qbittorrent:latest
ports:
- "8080:8080"
volumes:
- ./qbittorrent:/config
- /mnt/media/downloads:/downloads
restart: unless-stopped
This stack: Prowlarr indexes torrent sources → Radarr/Sonarr request and monitor downloads → qBittorrent downloads → files move to the Jellyfin media directory automatically.
Troubleshooting
Hardware Transcoding Not Working
# Verify /dev/dri/renderD128 exists and is accessible
ls -la /dev/dri/
# Check what group owns render device
stat /dev/dri/renderD128 | grep Gid
# Get the GID and update docker-compose.yml group_add
getent group render
If the render device’s group GID differs from 109 in your compose file, update group_add to match the actual GID from your system.
Video Plays But No Audio
Check audio format compatibility. Some clients can’t Direct Play specific audio codecs Dolby Atmos, DTS-X. In Jellyfin Playback settings → Audio, ensure audio format fallback is enabled. The server will remux the audio track to a compatible format.
Library Not Updating After Adding Files
Trigger a manual rescan: Dashboard → Libraries → Scan All Libraries. Or set the automatic scan interval in Dashboard → Scheduled Tasks → Scan Media Library.
Who Should Skip This Comparison
Frequently Asked Questions
Does Jellyfin have Live TV support?
Yes. Jellyfin supports HDHomeRun network tuners and IPTV playlists M3U format. Configure in Dashboard → Live TV. For a complete live TV and DVR solution: pair with an HDHomeRun Connect tuner and configure the guide data source.
Can Jellyfin run on the same mini PC as Home Assistant and Pi-hole?
Yes. On the EQ14 with 16GB RAM: Jellyfin 2-3GB active streaming, Home Assistant 1.5GB, Pi-hole 100MB, Nginx, and Portainer all run simultaneously with RAM to spare. Average idle power stays around 8-9W — Jellyfin transcoding spikes to 14-20W only while a stream is active.
How do I keep Jellyfin updated?
cd ~/jellyfin
docker compose pull && docker compose up -d
Pull the latest image and recreate the container. Config is preserved in the volume.
Does Jellyfin support 4K HDR?
Yes. 4K HDR content HDR10, Dolby Vision, HLG streams via Direct Play on compatible clients Apple TV 4K, Android TV boxes with HDR support. For clients that don’t support Direct Play of 4K HDR: hardware transcoding can tone-map HDR to SDR on Intel 12th Gen+ and AMD RDNA 3 hardware with the appropriate Jellyfin FFmpeg build.
Is Jellyfin safe to expose to the internet?
With proper setup: yes. Use Nginx Proxy Manager with Let’s Encrypt SSL and enable authentication in Jellyfin. Don’t expose port 8096 directly — proxy through Nginx. Enable two-factor authentication in Jellyfin for admin accounts. Keep Jellyfin updated to receive security patches.
Can a mini PC run Jellyfin Media Server?
Yes. Jellyfin runs on any mini PC with a 64-bit CPU, 2GB RAM, and adequate storage. The key advantage over Plex: hardware transcoding is completely free — no subscription required. The Intel N150 Beelink EQ14 handles 2-3 simultaneous 4K HEVC transcodes via VA-API. The Intel i5-12450H GEEKOM IT12 handles 4-6 simultaneous streams.
What is the best mini PC for Jellyfin?
The Beelink EQ14 with Intel N150 is the best Jellyfin mini PC for most households. VA-API hardware transcoding is free no Plex Pass needed, 7W idle power, and 16GB RAM handles Jellyfin alongside other home server services. For 4+ simultaneous 4K streams: the GEEKOM IT12 with Intel Quick Sync handles more concurrent transcodes.
