12 KiB
🎬 Jellyfin — Self-Hosted Media Server
📖 What is Jellyfin?
Jellyfin is a free, open-source media server that puts you in full control of your media library. It is the community-driven, privacy-respecting alternative to proprietary platforms like Plex and Emby — with no subscriptions, no tracking, and no vendor lock-in.
Jellyfin lets you collect, manage, and stream your movies, TV shows, music, live TV, photos, and books from your own server to any device, anywhere in the world.
✨ Key Features & Capabilities
🎥 Media Management
- Movies & TV Shows — Organizes your video library with rich metadata, posters, fan art, trailers, and ratings pulled from online databases (TMDb, TheTVDB, etc.)
- Music — Full music library management with MusicBrainz integration, album art, lyrics, and playlists
- Photos — Browse and share your photo collection; supports slideshow playback
- Books & Audiobooks — Manage eBooks and audiobooks (via plugins)
- Live TV & DVR — Watch and record live television using an HDHomeRun tuner or compatible TV backend (Tvheadend, NextPVR)
📡 Streaming & Playback
- Direct Play — Streams media in its original format with zero quality loss if the client supports it
- Transcoding — On-the-fly conversion of media to formats compatible with any client device
- Hardware Acceleration — Supports Intel Quick Sync, AMD AMF, NVIDIA NVENC, VA-API, and VideoToolbox for fast, low-CPU transcoding
- Adaptive Bitrate — Automatically adjusts quality based on your network connection
- Resume Playback — Tracks your watch progress across all devices
- SyncPlay — Watch content simultaneously with other users in perfect sync
👥 User Management
- Multiple Users — Create separate profiles with individual libraries, permissions, and parental controls
- Parental Controls — Restrict access by content rating, hide libraries, and set PIN-protected profiles
- Guest Access — Share your server with friends and family without giving full access
- Activity Logs — Full audit trail of who watched what and when
📺 Client Support
Jellyfin has official and community clients for virtually every platform:
- Web Browser — Built-in web UI accessible from any browser
- Android & Android TV
- iOS & Apple TV
- Roku
- Fire TV / Kodi
- Samsung Tizen & LG webOS Smart TVs
- Desktop — Windows, macOS, Linux
- Xbox (via browser or Kodi)
🔌 DLNA & Casting
- DLNA server support for smart TVs and media players
- Chromecast support via the web client
- AirPlay via community plugins
🔒 Privacy & Security
- 100% self-hosted — your data never leaves your server
- No telemetry — zero tracking or analytics by default
- Optional SSL/HTTPS — secure your server with Let's Encrypt or custom certificates
- API-first architecture — full REST API for automation and integrations
🧩 Plugin Ecosystem
Extend Jellyfin with community plugins:
- Open Subtitles & Subscene for automatic subtitle downloads
- Fanart.tv for enhanced artwork
- Ani-Sync for AniList/MyAnimeList integration
- Playback reporting & statistics dashboards
🖥️ Prerequisites
Before you begin, ensure you have the following installed on your Linux host:
| Requirement | Minimum Version | Check Command |
|---|---|---|
| Docker Engine | 24.x+ | docker --version |
| Docker Compose | v2.x+ (plugin) | docker compose version |
| Available RAM | 2 GB+ | free -h |
| Available Disk | Depends on library size | df -h |
⚠️ Linux Only: Running Jellyfin in Docker on Windows or macOS is not officially supported and hardware-accelerated transcoding will not work on those platforms. Install natively on Windows/macOS instead.
📁 Recommended Directory Structure
Before deploying, set up the following folder layout on your host machine:
jellyfin-deploy/
├── docker-compose.yml ← The compose file from this repo
├── jellyfin/
│ ├── config/ ← Jellyfin configuration & database (auto-created)
│ └── cache/ ← Transcoding cache (auto-created)
└── media/
├── movies/ ← Your movie files
├── tvshows/ ← Your TV show files
└── music/ ← Your music files
🚀 Installation Instructions
Step 1 — Install Docker
If Docker is not already installed, follow the official guide for your distribution:
# Ubuntu / Debian (quick install)
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER # Allow your user to run Docker without sudo
newgrp docker # Apply group change without logging out
Verify the installation:
docker --version
docker compose version
Step 2 — Clone or Download This Repository
git clone https://github.com/YOUR_USERNAME/jellyfin-docker.git
cd jellyfin-docker
Or simply create a working directory and place the provided files inside it:
mkdir jellyfin-deploy && cd jellyfin-deploy
# Copy docker-compose.yml and README.md here
Step 3 — Create Required Directories
mkdir -p jellyfin/config
mkdir -p jellyfin/cache
mkdir -p media/movies
mkdir -p media/tvshows
mkdir -p media/music
Your actual media files should be placed in (or symlinked from) the
media/subdirectories, or you can update the bind mount paths indocker-compose.ymlto point directly to where your media already lives.
Step 4 — Configure docker-compose.yml
Open docker-compose.yml in a text editor and customize the following:
4a. Set your Timezone
environment:
- TZ=America/New_York # ← Change to your timezone (e.g. Europe/London)
Find your timezone string at: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
4b. Set the Published Server URL (optional but recommended)
environment:
- JELLYFIN_PublishedServerUrl=http://YOUR_SERVER_IP_OR_DOMAIN:8096
Replace YOUR_SERVER_IP_OR_DOMAIN with your server's LAN IP (e.g., 192.168.1.100) or public domain name.
4c. Set Media Paths
By default, the compose file uses relative paths (./media/movies, etc.). To point at existing media folders elsewhere on your system, change the source: paths:
volumes:
- type: bind
source: /mnt/nas/movies # ← Your actual path
target: /media/movies
read_only: true
4d. Set User/Group (Recommended)
Find your current user's UID and GID:
id
# Example output: uid=1000(youruser) gid=1000(yourgroup)
Uncomment and update the user: line in docker-compose.yml:
user: "1000:1000"
This prevents Jellyfin from running as root and ensures correct file permissions.
Step 5 — Start Jellyfin
docker compose up -d
The -d flag runs the container in the background (detached mode).
Check that it started successfully:
docker compose ps
docker compose logs -f jellyfin
Step 6 — Complete the Setup Wizard
Open your browser and navigate to:
http://YOUR_SERVER_IP:8096
You will be greeted by the Jellyfin Setup Wizard. Follow these steps:
- Create your admin account — Set a username and password
- Add media libraries — Point Jellyfin to
/media/movies,/media/tvshows,/media/music(these are the container-side paths) - Choose metadata language — Select your preferred language for scraped info
- Configure remote access — Enable if you want to access Jellyfin outside your home network
- Finish — Jellyfin will begin scanning your media library immediately
🛑 Managing the Container
| Action | Command |
|---|---|
| Start | docker compose up -d |
| Stop | docker compose down |
| Restart | docker compose restart jellyfin |
| View logs | docker compose logs -f jellyfin |
| Update image | docker compose pull && docker compose up -d |
| Remove container & volumes | docker compose down -v |
⚡ Hardware Acceleration (Optional)
Hardware transcoding dramatically reduces CPU usage during video playback.
Intel / AMD (VA-API via /dev/dri)
Uncomment the devices section in docker-compose.yml:
devices:
- /dev/dri:/dev/dri
Then in the Jellyfin Admin Dashboard:
- Go to Dashboard → Playback → Transcoding
- Set Hardware acceleration to Video Acceleration API (VAAPI)
- Set the VA-API device to
/dev/dri/renderD128 - Save and test
NVIDIA GPU
Requires the NVIDIA Container Toolkit. Add to docker-compose.yml:
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
Then in Jellyfin, set Hardware acceleration to NVENC.
🌐 Exposing Jellyfin to the Internet (Optional)
Option A — Port Forwarding
Forward TCP port 8096 on your router to your server's LAN IP.
Option B — Reverse Proxy with HTTPS (Recommended)
Use Nginx Proxy Manager, Traefik, or Caddy in front of Jellyfin to enable HTTPS. Example Nginx config snippet:
server {
listen 443 ssl;
server_name jellyfin.yourdomain.com;
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;
}
}
🔧 DLNA Configuration (Optional)
For DLNA support (smart TVs discovering Jellyfin automatically), you need host networking:
network_mode: host
⚠️ When using host networking, remove the
ports:section entirely — host network mode exposes all ports directly.
🗂️ Backup & Restore
The only directory you need to back up is ./jellyfin/config/. This contains:
- The Jellyfin database (
jellyfin.db) - All server settings and user data
- API keys and plugin configurations
# Backup
tar -czf jellyfin-backup-$(date +%Y%m%d).tar.gz ./jellyfin/config
# Restore
tar -xzf jellyfin-backup-YYYYMMDD.tar.gz
🐛 Troubleshooting
| Problem | Solution |
|---|---|
| Port 8096 not accessible | Check firewall: sudo ufw allow 8096/tcp |
| Permission denied on media | Set correct user: UID:GID in compose file |
| Media not appearing | Check that bind mount paths are correct; restart and re-scan |
| High CPU during playback | Enable hardware acceleration; ensure Direct Play is used when possible |
| Container won't start | Run docker compose logs jellyfin to inspect errors |
📚 Useful Links
- 🏠 Jellyfin Official Website
- 📖 Official Documentation
- 🐳 Docker Hub Image
- 💬 Jellyfin Forum
- 🔌 Plugin Catalogue
- ⚡ Hardware Acceleration Guide
- 🛡️ Backup & Restore Guide
📜 License
Jellyfin is released under the GNU General Public License v2.0. This deployment configuration is provided as-is for personal use.
Made with ❤️ for the self-hosting community