AI-generated content
A self-hosted media server gives you complete control over your content library, no subscriptions, and the ability to stream to any device.
The Stack
| Component | Choice | Why |
|---|---|---|
| Server | Jellyfin | Free, open-source, no vendor lock-in |
| OS | Ubuntu Server 24.04 | Stable, good hardware support |
| Storage | ZFS on RAID-Z | Data integrity, snapshots, compression |
| Transcoding | NVIDIA NVENC / Intel QSV | Hardware-accelerated, low CPU |
| Client | Jellyfin web + mobile apps | Cross-platform, no extra cost |
Why Jellyfin Over Alternatives?
- Plex: Requires paid subscription for hardware transcoding
- Emby: Same — hardware transcoding is a paid feature
- Jellyfin: 100% free and open-source, all features unlocked
Setup
1. Install Jellyfin
curl -fsSL https://repo.jellyfin.org/install.deb.sh | sudo bash
sudo apt install jellyfin
sudo systemctl enable --now jellyfin
2. Configure Hardware Transcoding
NVIDIA:
# Install NVIDIA drivers and container runtime
sudo apt install nvidia-driver-550
sudo systemctl enable --now nvidia-container-runtime
Intel Quick Sync:
# Install Intel media drivers
sudo apt install intel-media-va-driver-non-free
# Verify
vainfo
3. Set Up Your Library
- Open Jellyfin at
http://<server-ip>:8096 - Create admin account
- Add media folders:
/media/movies/media/tv-shows/media/music
- Set metadata fetcher to The Movie Database (TMDB)
4. Network Streaming
For remote access:
- Option A: WireGuard VPN (recommended)
- Option B: Tailscale (easiest)
- Option C: Reverse proxy with Caddy (advanced)
Organizing Your Media
Jellyfin relies on proper file naming:
/media/movies/
Inception (2010)/
Inception (2010).mkv
Inception (2010)-poster.jpg
/media/tv-shows/
Breaking Bad/
Season 01/
Breaking Bad - S01E01 - Pilot.mkv
Breaking Bad - S01E01 - Pilot.nfo
Performance Tuning
SSD Cache (L2ARC)
If you have an SSD:
# Add SSD as L2ARC read cache
sudo zpool add tank cache /dev/nvme0n1
Transcode Limits
Set limits in Jellyfin dashboard:
- Max streaming quality: 1080p (or your bandwidth allows)
- Concurrent streams: Based on your server capacity
- Bitrate limits: Match your home network
Maintenance
Regular Tasks
| Task | Frequency | Command |
|---|---|---|
| Update Jellyfin | Monthly | sudo apt update && sudo apt upgrade jellyfin |
| Clean transcoding temp files | Weekly | sudo systemctl restart jellyfin |
| Refresh metadata | Monthly | Dashboard > Library > Refresh metadata |
| Check ZFS health | Weekly | zpool status |
| Backup library database | Weekly | cp /var/lib/jellyfin/var/db/*.db /backup/ |
Monitoring
Use Prometheus + Grafana for:
- Transcoding load
- Storage usage
- Network throughput
- System health
Troubleshooting
Subtitles not showing: Enable subtitles in playback settings, ensure .srt files are named matching the video file.
Transcoding fails: Check GPU passthrough, verify vainfo works, check Jellyfin logs at /var/log/jellyfin/.
Slow library scan: Exclude large files in settings, ensure media folders aren’t on network drives.
Budget Build
| Component | Cost |
|---|---|
| Used Mini PC (i5-12400) | $200 |
| 16 GB RAM | $40 |
| 1 TB NVMe (system) | $60 |
| 4 TB HDD (media) | $80 |
| Total | ~$380 |
This setup can transcode 1080p to 4K for multiple simultaneous streams.
This post was generated with AI assistance. Review and customize it to match your experience.