How to Set Up a Self-Hosted Media Server with Jellyfin
Stream your own movies, TV shows, and music to any device in your home -- with a free, open-source server that has no subscription, no ads, and no telemetry. About 20 minutes to install.
01. What Is Jellyfin?
Jellyfin is a free, open-source media server. You point it at folders on your own disk -- your ripped movies, downloaded TV shows, MP3 library -- and it serves them up to a polished app on your phone, tablet, smart TV, web browser, or any other device on your network. You get album art, plot summaries, posters, watched-progress tracking, multiple user profiles, and a Netflix-style "Continue Watching" row, all from your own files on your own hardware.
The closest commercial analogue is Plex, but Jellyfin has three distinguishing features that matter for a lot of self-hosters: it is fully free with no "Plex Pass" paywall for hardware transcoding, mobile streaming, or downloads; it is open-source under the GPL, so it cannot be acquired and enshittified by a private buyer; and it does not phone home with usage data -- the server is entirely under your control.
The trade-off is that Jellyfin is a bit more hands-on than Plex out of the box, particularly around metadata and transcoding. For most home users with a modest library those are one-time setup costs. This guide walks you through every one of them.
The mental model: a media server has two halves. A backend (the Jellyfin server process, running on your Linux box or NAS) that reads your files, fetches metadata from the internet, and serves video over HTTP. And a frontend (any Jellyfin app on any device) that talks to the backend, fetches the catalog, and plays or casts the stream. The backend reads files; the frontends are slim clients.
What this guide covers
- •What hardware and software you need before you start.
- •Installing Jellyfin's official Docker image -- the cleanest, simplest setup.
- •The first-run wizard: admin account, library setup, metadata sources.
- •Installing client apps on the devices you actually want to watch on.
- •How to organize your media folders so Jellyfin matches the right posters and metadata.
- •Optional: hardware transcoding, multi-user sharing, and tips for keeping the server healthy.
Step 1. Gather Your Requirements
Jellyfin is not demanding. A modest Linux box, a NAS appliance, or a spare mini PC will all run it comfortably for direct-play (no transcoding) workloads. The thing that tends to actually bite is disk space -- video adds up fast, and a flaky network mount can wreck playback. Get the basics right first.
Host machine
- •A Linux server or NAS that can run Docker. A NUC, a Raspberry Pi 4 or 5 (Pi 3 struggles with transcoding but is fine for direct play), a Synology or QNAP with Docker support, or a full-fat home lab box. 2GB of RAM is plenty for direct play; 8GB if you will run other containers alongside it.
- •Docker installed on the host. If you do not have it yet, follow our Docker install guide first -- this whole setup is one container.
- •A stable IP for the host. Either set a static IP on the server itself, or reserve a DHCP lease in your router for the host's MAC address. The clients will use this IP to reach the server.
Storage
- •Media files on disk. A 4TB external USB drive is enough to start with hundreds of movies and shows. Internal drives are faster; network mounts (NFS/SMB) work but introduce a failure point if the network hiccups.
- •A separate path for Jellyfin's config so container updates preserve your libraries and watched history. We will use a named Docker volume for this.
- •Filesystem tip: ext4 on Linux is fine for media. Avoid NTFS on Linux if possible -- it has worse permissions handling and slower metadata operations. ZFS is overkill for most home setups unless you already run it.
Clients (where you will watch)
You do not need anything specific before installing the server, but plan the client end now. Jellyfin has official apps for:
- •Android and Android TV (Google Play Store, F-Droid, or direct APK from the Jellyfin downloads page).
- •iPhone and iPad (App Store). The iOS app is a few dollars one-time, which funds the project.
- •Roku (Roku Channel Store).
- •Web browser -- any modern browser works, including casting from Chrome to a Chromecast.
- •Fire TV via the official Android TV APK sideloaded.
A note on transcoding: if all your media is in formats your clients can play natively (H.264 MP4 for Apple, HEVC for newer devices), the server does almost no work. If you have a mix of odd formats or remote clients with bad bandwidth, the server transcodes live -- and that benefits from a CPU with Quick Sync (Intel) or a discrete GPU. We cover enabling hardware transcoding in the Tips section once the basic setup is working.
Step 2. Install Jellyfin With Docker
The official Jellyfin Docker image bundles everything you need -- the server, the web UI, and all the
necessary metadata scrapers -- in one container. A single docker run
command is enough to get a working server up. We mount two paths: one for Jellyfin's own configuration
(so updates do not wipe your library) and one for your media files.
Run this command on the host (SSH in or open a terminal):
docker run -d \ --name jellyfin \ -v jellyfin-config:/config \ -v /path/to/media:/media \ -p 8096:8096 \ --restart=unless-stopped \ jellyfin/jellyfin
What each flag does
- -dRun the container in the background.
- --name jellyfinGive the container a friendly name for easy management with
docker logs,docker stop, etc. - -v jellyfin-config:/configPersist Jellyfin's config, libraries, and metadata in a named Docker volume so nothing is lost on updates.
- -v /path/to/media:/mediaMount your actual media folder into the container at
/media. Replace the left side with the real path on your host, e.g./mnt/storage/media. You can mount multiple volumes if your media is split across drives. - -p 8096:8096Publish Jellyfin's HTTP port (8096) to the host so clients can reach it.
- --restart=unless-stoppedAuto-restart the container on reboot or crash. You want the media server available without manual intervention.
- jellyfin/jellyfinThe official image, pulled from Docker Hub on first run.
First run downloads the image (a few hundred MB) and
initializes the config directory. Watch the logs with
docker logs -f jellyfin and wait for a line like
[INF] Found data path to be "/config" followed by
[INF] Server starting up.... That means the web UI is ready.
Multiple media drives
If your media is spread across several disks or shares, mount each one as its own volume:
docker run -d --name jellyfin \ -v jellyfin-config:/config \ -v /mnt/movies:/media/Movies \ -v /mnt/tv:/media/TV\ Shows \ -v /mnt/music:/media/Music \ -p 8096:8096 --restart=unless-stopped jellyfin/jellyfin
Inside the container, the paths you actually add to Jellyfin are /media/Movies,
/media/TV Shows, and so on. The host-side paths do not matter to
Jellyfin directly.
Permissions gotcha
The Jellyfin container runs as a non-root user by default. If you see permission errors when it tries
to read your media, either make the media folder readable by all users (chmod -R a+r /path/to/media),
or pass the --user $(id -u):$(id -g) flag to docker run
to make the container run as your own user ID.
Step 3. Run the First-Setup Wizard
The first time you visit Jellyfin in a browser you go through a short wizard that sets up the admin account, adds your media libraries, and chooses default metadata providers. Walk through it carefully -- getting the libraries right here saves a lot of fixing later.
Open Jellyfin in a browser on any device on your network:
http://<server-ip>:8096
For example, if your server is at 192.168.1.50, the URL is
http://192.168.1.50:8096. Any browser on any device on the same
network works -- your phone, your laptop, even a smart TV's built-in web browser if it has one.
The wizard, step by step
- 1.Welcome screen -- choose your language and click Next.
- 2.Create the admin account. Pick a username and a strong password. This account can add other users, change settings, and see every library. Use a real password, not "admin/admin".
- 3.Set up your media libraries. This is the important screen. You will add one library at a time, choosing a content type (Movies, TV Shows, Music, Books, etc.) and pointing Jellyfin at a folder inside the container's
/mediamount.
Adding the first library: Movies
- 1.Click "Add Media Library".
- 2.Content type: Movies. Leave "Movie" as the type.
- 3.Click the + next to Folders and navigate to
/media/Movies. (If you mounted the volume differently in Step 2, pick the matching sub-path.) - 4.Leave the rest on defaults for now. You can fine-tune metadata languages and preferred download languages later in Library settings.
- 5.Click OK. Jellyfin scans the folder, identifies each movie by filename, fetches posters and metadata from themoviedb.org, and adds them to your library.
Repeat for TV Shows and Music
Go back to the library list and add two more libraries the same way:
- •TV Shows -- content type "Shows", pointed at
/media/TV Shows. Jellyfin expects this folder to contain one subfolder per show, and within that one subfolder per season (see Step 5). - •Music -- content type "Music", pointed at
/media/Music. Jellyfin expects one subfolder per artist, then per album, with the audio files inside.
Final wizard screens
- 1.Metadata language -- pick the language you want posters and plot summaries in. Default English pulls metadata from TheMovieDB and TheTVDB using English.
- 2.Country/region -- affects which country's release dates and ratings show up. Pick your home country.
- 3.Allow remote connections -- leave this OFF for now if you only watch at home. We come back to remote access in a later step. Turning it on blind exposes your server to the internet without auth on top.
- 4.Finish. You land on the home screen, populated with whatever movies Jellyfin already scanned. Depending on library size, the initial scan can take a few minutes to a couple of hours.
If a show does not match: open the library in Jellyfin, find the unmatched item, click the three-dot menu, choose "Identify", and type the show's exact name and release year. Jellyfin will re-search and usually pick up the correct metadata on the second pass.
Step 4. Install Client Apps
The server is up. Now you want to actually watch things on something other than the browser tab the server is running in. Jellyfin has apps for every common client device. The experience is broadly the same on all of them: launch the app, point it at the server URL, log in with your admin account (or a user account you can create in the dashboard), and start browsing.
Web browser
- •Chrome, Firefox, Edge, Safari all work directly via
http://server-ip:8096. This is the simplest way to test -- no install needed. - •Casting: from Chrome on a laptop, click the cast icon in the Jellyfin player to send the stream to a Chromecast on the same network. The Jellyfin server handles the transcoding if the Chromecast cannot play the source format.
Android and Android TV
- 1.Install "Jellyfin" from the Google Play Store on phones, or from the Play Store on Android TV / Google TV. The same app works on both.
- 2.Alternatively, install from F-Droid (the open-source Android repo) for the FOSS build with no Google dependencies.
- 3.First launch prompts for the server address. Type
http://server-ip:8096and log in with your admin account.
iPhone and iPad
- 1.Install "Jellyfin Mobile" from the App Store. It is a small one-time purchase that funds the project.
- 2.For an entirely free option, install "Infuse 7" from the App Store (free with a Pro subscription for some features) -- it works as a Jellyfin client and has arguably the best iOS player of any media client.
- 3.Point the app at
http://server-ip:8096and log in.
Roku
- 1.Open the Roku Channel Store on the device and search for "Jellyfin".
- 2.Add the channel and launch it. The first launch prompts for the server URL.
Fire TV
Amazon does not list Jellyfin in its store directly. The simplest route is:
- 1.Install "Downloader" from the Fire TV app store.
- 2.Open Downloader and enter the URL
jellyfin.org/downloads/, then download the Android TV APK. - 3.Fire TV will prompt to install the APK once downloaded. Allow it.
- 4.Launch Jellyfin and point it at your server.
Testing all the clients. Once the apps are installed, log in
with the admin account on one device, play a movie, and check that the playback begins within a few
seconds. If playback stalls or falls back, the client cannot direct-play the file and the server is
transcoding -- check server CPU usage with docker stats jellyfin
during playback to confirm.
Step 5. Organize Your Media Folders
Jellyfin matches filenames against online databases to fetch posters, summaries, cast lists, and episode titles. The better your folders and file names follow convention, the more accurate the matches are. A few minutes of tidying now saves hours of clicking "Identify" later.
Movies
One folder per movie, with the year in parentheses. Jellyfin uses the folder name (and falls back to the filename) to match against TheMovieDB.
/media/Movies/ The Matrix (1999)/ The Matrix (1999) [1080p].mkv The Matrix Reloaded (2003)/ The Matrix Reloaded (2003).mkv Arrival (2016)/ Arrival (2016).mp4
You can put all the movie files flat in /media/Movies/
without per-movie folders, and it works fine -- the per-movie folders are optional but help when you
want to add poster images, subtitles, or bonus features alongside the main file.
TV Shows
One folder per show, then one folder per season. Episode files use the
SxxExx naming convention that Jellyfin parses automatically.
/media/TV Shows/ Breaking Bad/ Season 01/ Breaking Bad - S01E01.mkv Breaking Bad - S01E02.mkv Season 02/ Breaking Bad - S02E01.mkv The Expanse/ Season 01/ The Expanse - S01E01.mkv
You can skip the per-season folders and put all episodes directly inside the show folder -- Jellyfin
will figure out which episode is in which season from the SxxExx
number alone. Season folders just make manual browsing easier.
Music
One folder per artist, then per album. Tag your audio files with proper ID3 tags (artist, album, track title, track number) using a tagger like MusicBrainz Picard -- Jellyfin reads the tags more than the filenames for music.
/media/Music/ Fleetwood Mac/ Rumours/ 01 - Second Hand News.flac 02 - Dreams.flac Daft Punk/ Random Access Memories/ 01 - Give Life Back to Music.flac
Triggering a library rescan
After you add new files to disk, Jellyfin usually picks them up within a few minutes (it watches the folders for changes). To force an immediate scan:
- 1.In the web UI, go to Dashboard → Libraries and click the three-dot menu next to a library.
- 2.Choose Scan Library. Pick "Scan for new and updated files" for the fast path, or "Replace all metadata" if you want Jellyfin to re-fetch posters and summaries for everything.
Real-time monitoring. By default Jellyfin watches each library folder for filesystem changes and scans within seconds of a new file landing. If your media is on a network mount (NFS, SMB) this may not work reliably -- in that case, schedule a periodic library scan under Dashboard → Libraries → Advanced → "Scan media libraries" scheduled task.
Quick Tips
- •Enable hardware transcoding if you have a GPU. Without it, Jellyfin transcodes video on the CPU, which struggles beyond one stream. Open Dashboard → Playback → Transcoding and pick your hardware (Intel Quick Sync via
/dev/dri, NVIDIA via/dev/nvidia0). You then need to pass the relevant device into the container with--device /dev/dri:/dev/drior--gpus all. The speed-up is dramatic -- 5x or more on supported formats. - •Use Jellyfin Media Analyzer or JellyScraper for stubborn metadata. Some niche or non-English content does not auto-match. The "Identify" dialog in the web UI lets you enter a TMDB or TVDB ID directly for a guaranteed match.
- •Share with family via separate user accounts. Dashboard → Users → "+" adds accounts. Each gets their own watch history, "Continue Watching", and can be limited to specific libraries -- useful for keeping kids' viewing separate from yours.
- •Enable remote access securely with a reverse proxy. For outside-the-home access, do NOT just port-forward 8096 raw to the internet. Put Jellyfin behind a reverse proxy (Caddy, Traefik, or nginx) with TLS and use Jellyfin's built-in HTTPS support. Combine with a VPN like WireGuard for the most private solution.
- •Prefer direct play over transcoding. Modern phones and Apple TVs handle H.264 and HEVC in MP4/MKV natively. If most of your library is in those formats, the server barely works and you avoid the transcoding bottleneck entirely. Use HEVC for new rips to save space and bandwidth.
- •Keep the container updated. Pull the latest image with
docker pull jellyfin/jellyfin, then recreate the container with the same launch command. The config volume preserves all your libraries, users, and settings. Major container updates land every few months. - •Schedule overnight metadata refreshes. Dashboard → Scheduled Tasks shows the entire maintenance list. Set "Refresh metadata" to run nightly so newly-released info (episode summaries for an in-progress season, for example) gets pulled without manual intervention.
- •Back up the config volume. The
jellyfin-confignamed Docker volume contains all your metadata, libraries, and user accounts. A periodicdocker run --rm -v jellyfin-config:/data -v /backup:/backup alpine tar czf /backup/jellyfin-config.tgz /datasnapshots it. Restoring is the same command with reversed paths. - •Add subtitles next to your video files. Jellyfin picks up external
.srtor.assfiles automatically if they share the video file's base name, e.g.Movie (2020).mkv+Movie (2020).en.srt. No extra setup needed.
Need More Help?
Setting up Jellyfin itself is fast; the parts that bite people are hardware transcoding permissions, getting stubborn media to match metadata, and setting up secure remote access. We can walk through your specific hardware, get transcoding working, secure the install, and verify everything plays cleanly -- book a free call.