Last updated September 2026. Some links on this page may be affiliate links, which means RPi4U may earn a small commission at no extra cost to you.
By the end of this guide your Raspberry Pi 5 will run Jellyfin, a free and open-source media server. It serves the movies, shows and music on a USB drive to your TV, phone and laptop, with posters, episode info and resume points. There are no accounts to sign up for and no subscription.
One thing to know up front: the Pi 5 has no hardware video encoder, so it is great at sending files as they are (direct play) but slow at converting them on the fly (transcoding). This guide shows you how to set things up so most playback stays direct.
At a glance
| Difficulty | Intermediate |
| Time | About 60 minutes, plus library scan time |
| Works on | Pi 5 (4GB or more) · Pi 4 (direct play) |
| Parts cost (approx, US) | About $128 (Pi 5 4GB $110, power supply $12, cooler $6), plus a drive |
What you need
- Raspberry Pi 5 with 4GB of RAM or more
- Official 27W USB-C power supply (a 3A supply limits USB devices to 600mA, which can starve a bus-powered drive)
- Active Cooler, since library scans keep the CPU busy
- microSD card (16GB or larger) for the operating system
- External USB drive for your media, or an M.2 HAT+ with an NVMe SSD
- Ethernet cable to your router
- A computer to flash the microSD card and to run the setup wizard in a browser
Step 1: Flash Raspberry Pi OS Lite (64-bit)
A media server does not need a desktop, so the Lite version leaves more memory for Jellyfin. The current release is based on Debian 13 “Trixie”.
- Install Raspberry Pi Imager on your computer and insert the microSD card.
- Choose Raspberry Pi 5 as the device.
- For the operating system, pick Raspberry Pi OS Lite (64-bit) from the other Raspberry Pi OS options.
- Select your microSD card as the storage.
- In the customization settings, set a hostname such as
jellyfin, create a username and password, and turn on SSH. - Write the card, put it in the Pi, plug in Ethernet and power, and give it a couple of minutes to boot.
Use wired Ethernet rather than Wi-Fi. High-bitrate 1080p and 4K files need a steady stream that Wi-Fi often can’t hold, which shows up as buffering.
From your computer, log in over SSH (swap in your username) and update everything:
ssh yourname@jellyfin.local
sudo apt update && sudo apt full-upgrade -y
Step 2: Attach and auto-mount the media drive
Plug the drive into one of the blue USB 3 ports. Then find its name:
lsblk
Your microSD card shows up as mmcblk0. The USB drive is usually sda, with a partition called sda1. Match it by size to be sure. (An NVMe SSD on an M.2 HAT+ appears as nvme0n1 with a partition like nvme0n1p1.)
Optional: format as ext4
ext4 is the Linux-native format and makes permissions simple. Formatting erases everything on the partition, so only do this on an empty drive or one you have backed up:
sudo mkfs.ext4 -L media /dev/sda1
If your drive already holds media in exFAT (common for drives filled on Windows or macOS), you can keep it. Install support first with sudo apt install exfat-fuse.
Add the drive to /etc/fstab
Device names like sda1 can change between boots, so mount by UUID instead. Print it:
sudo blkid /dev/sda1
Copy the UUID="..." value (not PARTUUID). Create a mount point and open the file system table:
sudo mkdir -p /mnt/media
sudo nano /etc/fstab
Add one line at the bottom, using your own UUID. For an ext4 drive:
UUID=1234abcd-5678-90ef-1234-567890abcdef /mnt/media ext4 defaults,nofail 0 2
For an exFAT drive, use this form instead. The umask=022 part lets every user on the Pi, including Jellyfin, read the files:
UUID=ABCD-1234 /mnt/media exfat defaults,nofail,uid=1000,gid=1000,umask=022 0 0
The nofail option matters: without it, the Pi can stop at an emergency prompt during boot if the drive is unplugged. Save with Ctrl+O, exit with Ctrl+X, then test the entry before you reboot:
sudo systemctl daemon-reload
sudo mount -a
df -h /mnt/media
If df shows the drive’s size, the line is good. If mount -a prints an error, fix it before rebooting.
Step 3: Organize folders and set permissions
Jellyfin runs as its own system user called jellyfin, not as you. It needs read access to every media folder and execute (traverse) access on every folder above them. On an ext4 drive, create one folder per media type and make yourself the owner so you can copy files in:
sudo mkdir -p /mnt/media/Movies /mnt/media/Shows /mnt/media/Music
sudo chown -R $USER:$USER /mnt/media
chmod -R a+rX /mnt/media
The a+rX setting gives everyone read access to files and lets them open folders, without making files executable. Rerun the chmod line if new files arrive with tight permissions. On exFAT, the mount options from Step 2 already handle this.
Naming tips
Jellyfin matches artwork and descriptions by name, so a tidy layout saves a lot of manual fixing:
- Movies: one folder per film, named with the year, and the file named the same way:
Movies/Big Buck Bunny (2008)/Big Buck Bunny (2008).mkv - Shows: a folder per series, then
Season 01,Season 02and so on (spell out “Season”), with episodes tagged likeS01E03:Shows/My Show (2021)/Season 01/My Show S01E03.mkv - Hard-to-match titles: add a provider ID in square brackets, such as
[imdbid-tt1234567], to the folder name. - Keep movies, shows and music in separate top-level folders so each library has one type of content.
Step 4: Install Jellyfin
Jellyfin’s official method for Raspberry Pi OS is an install script that adds the Jellyfin repository, then installs the server, web interface and Jellyfin’s FFmpeg build. Download it with its checksum and verify it:
curl -s https://repo.jellyfin.org/install-debuntu.sh -O
curl -s https://repo.jellyfin.org/install-debuntu.sh.sha256sum -O
sha256sum -c install-debuntu.sh.sha256sum
You should see install-debuntu.sh: OK. If you like, read through the script with less install-debuntu.sh (press Q to quit). Then run it:
sudo bash install-debuntu.sh
The script supports Debian Trixie on arm64, so it works on current Raspberry Pi OS. When it finishes, it prints the address of your server. Check that the service is running:
systemctl status jellyfin
Because Jellyfin now comes from an apt repository, your normal sudo apt update && sudo apt full-upgrade -y keeps it up to date.
Step 5: Run the setup wizard
On your computer, open http://jellyfin.local:8096 in a browser. If that name does not resolve, use the IP address the install script printed (or run hostname -I on the Pi).
- Pick your display language.
- Create the administrator account. Use a strong password.
- Add your libraries. Click the add button, choose a content type (Movies, Shows or Music), give it a name, and add the matching folder, for example
/mnt/media/Movies. Repeat for each type. You can also skip this and add libraries later from the Dashboard. - Choose your preferred metadata language and country.
- On the networking screen, leave remote access off for now if you only plan to watch at home.
- Finish, then sign in with your new account.
The first scan of a large collection can take a while, since Jellyfin fetches artwork for every title.
Step 6: Install client apps and aim for direct play
Jellyfin has official apps for Android, Android TV and Fire TV, iPhone and iPad, Roku, LG webOS, Samsung Tizen and Xbox, plus Jellyfin Media Player for desktop computers. Any web browser works too. Find them on the Jellyfin clients page or in your device’s app store, then enter your server address to connect.
Why transcoding is a problem on a Pi
When a client cannot play a file’s video or audio format, Jellyfin converts it on the fly. The Pi 5 has no hardware video encoder, and Jellyfin has deprecated its Raspberry Pi hardware acceleration (V4L2) for both the Pi 4 and Pi 5. So every transcode runs on the CPU. A Pi 5 may manage a single lower-resolution stream, but 4K or HEVC transcoding will stutter.
Leave hardware acceleration set to none in the Dashboard’s playback settings, and set things up so files play as they are:
- Prefer H.264 video with AAC audio in MP4 or MKV files. Almost every client plays these directly.
- Use HEVC (H.265) or 4K files only with clients you know support them, such as many recent smart TVs and streaming sticks.
- Pick text subtitles (SRT) over image-based ones. Image subtitles often have to be burned into the video, which forces a transcode.
- In each client’s settings, set the streaming quality to the maximum so it does not ask the server to shrink the video.
- While a video plays, open the Dashboard on another device. The active session shows whether it is direct playing or transcoding, and why.
Troubleshooting
- Library is empty or the folder is missing in the picker: Jellyfin cannot read it. Run
sudo -u jellyfin ls /mnt/media/Movies. If you get “Permission denied”, repeat thechmod -R a+rX /mnt/mediastep, then rescan the library. - Drive is not mounted after a reboot: run
lsblkandsudo mount -ato see the error. Check that the UUID in/etc/fstabmatchesblkidexactly, and that the file system type is correct. - Drive disconnects or clicks: use the 27W power supply, or a drive with its own power adapter or a powered USB hub.
- Playback buffers or stutters: check the Dashboard. If it says transcoding, change the client’s quality setting or use a more compatible file. If it says direct play, switch the Pi and the client to wired Ethernet.
- Can’t reach port 8096: run
systemctl status jellyfin. If it is not active, restart it withsudo systemctl restart jellyfinand try the IP address instead of the hostname.
Where to go next
- Want ad blocking for every device on the same network? Set up Pi-hole on a second Pi.
- Planning a bigger library or more viewers? Compare RAM and storage options in our Raspberry Pi buying guide.
- Not sure which board suits your next project? Try the Pi picker.
Sources: Jellyfin: Linux installation, Jellyfin repo helper scripts, Jellyfin: Setup wizard, Jellyfin: Hardware acceleration, Jellyfin: Movies, Jellyfin: Shows, Jellyfin: Clients, Raspberry Pi: External storage, Raspberry Pi hardware, Raspberry Pi OS downloads