Tucker
21 min video
3 min read
Build Your Own Media Server with Raspberry Pi
You just saved 18 min.
The big takeaway
Complete guide to setting up a Raspberry Pi as a self-hosted media server running Jellyfin and Immich for photos, movies, and TV shows, accessible remotely via Tailscale VPN.
Hardware Setup & OS Installation
Essential Kit Components
The Canit kit includes a Raspberry Pi 5, 128 GB SD card, case, heat sink, fan, power supply, and USB micro SD card reader. You'll need to separately provide an Ethernet cable and external storage (e.g., 1 TB SSD).
1
Raspberry Pi 5
2
128 GB SD card
3
Case with heat sink and fan
4
Power supply (USB-C)
5
USB micro SD card reader
6
External storage (1 TB SSD recommended)
Kit contents and additional items needed
OS Installation Process
Download Raspberry Pi Imager from raspberrypi.com/software, select Pi 5 model, choose Raspberry Pi OS Light, set hostname to 'media pi', create username and password, enable SSH with password authentication, and write to the micro SD card (takes about 10 minutes).
1
Download Raspberry Pi Imager for your OS
2
Select Pi 5 model and Raspberry Pi OS Light
3
Set hostname (e.g., 'media pi')
4
Create username and password
5
Enable SSH with password authentication
6
Write to micro SD card (~10 minutes)
OS installation workflow
Physical Assembly Steps
Install heat sink on the Pi, connect the fan to the fan port (yellow wire facing outward), snap the Pi into the case bottom piece, align the middle piece, and snap the fan into the top piece. Insert the micro SD card firmly into the slot on the back.
1
Apply heat sink to Pi processor
2
Connect fan to fan port (yellow wire outward)
3
Snap Pi into case bottom piece
4
Align and snap middle case piece
5
Snap fan into top case piece
6
Insert micro SD card into back slot
Physical assembly sequence
Connectivity & Power
Plug the USB-C power supply into the port marked 'power', connect an Ethernet cable to the Ethernet port and router for stable internet, and plug the external hard drive into a USB port. Warning: the external drive will be erased, so back up any data first.
System Configuration & Storage Setup
SSH Connection & Initial Updates
Connect to the Pi via SSH using 'ssh tucker@media.local' (replace 'tucker' with your username), then run 'sudo apt update && sudo apt full-upgrade -y' to fully update all software. Reboot with 'sudo reboot' and reconnect.
External Drive Formatting & Mounting
List connected devices with 'lsblk', then chain commands to unmount, wipe, create a GPT partition table, build an ext4 filesystem, and mount the drive to /mnt/storage. Add the drive's UUID to /etc/fstab to ensure it persists after reboot.
1
List devices with lsblk to identify drive (e.g., sda)
2
Unmount partition: sudo umount /dev/sda1
3
Wipe filesystem: sudo wipefs -a /dev/sda
4
Create GPT partition table: sudo parted /dev/sda script mklabel gpt
5
Create partition: sudo parted /dev/sda script mkpart primary ext4 0% 100%
6
Build ext4 filesystem: sudo mkfs.ext4 -L bulk /dev/sda1
7
Mount to /mnt/storage and add UUID to /etc/fstab
External drive setup and mounting
Directory Ownership & Folder Structure
Change ownership of /mnt/storage to your user with 'sudo chown -r user:user /mnt/storage', then create subdirectories for image and jellyfin (config, cache, media folders). This prevents permission errors when accessing the drive.
Docker & Immich Photo Management
Docker Installation
Run the official Docker install script via curl, add your user to the docker group with 'sudo usermod -a G docker $user', exit and reconnect via SSH, then verify with 'docker run --rm hello-world' and check version with 'docker compose version'.
Immich Setup & Configuration
Create an immich directory, download the docker-compose.yml and .env files from GitHub, edit the .env file to set timezone and other variables, then start with 'docker compose up -d'. Access at media.local:2283 to create a local account and configure photo backup.
1
Create ~/immich directory and cd into it
2
Download docker-compose.yml and .env from GitHub
3
Edit .env file with timezone and configuration
4
Start containers: docker compose up -d
5
Verify with: docker compose ps
6
Access at media.local:2283 in browser
Immich installation and startup
3-2-1 Backup Rule for Photos
Keep three total copies of photos on two different types of media with one copy kept offsite. Immich alone is not sufficient as a sole backup; consider keeping an extra drive at a friend's house or performing periodic backups to protect against drive failure or disaster.
3-2-1
Backup rule: 3 copies, 2 media types, 1 offsite
Recommended backup strategy for photo safety
Jellyfin Media Server Setup
Jellyfin Installation & Configuration
Create a ~/jellyfin directory, write a docker-compose configuration using printf, create bind mount folders (config and cache), then start with 'docker compose up -d'. Access at media.local:8096 to set language, create an admin user, and configure media libraries for movies and TV.
1
Create ~/jellyfin directory with config and cache subdirs
2
Write docker-compose.yml with printf command
3
Verify user ID matches 1000:1000 with id -u and id -g
4
Start containers: docker compose up -d
5
Access at media.local:8096
6
Create admin user and media libraries
Jellyfin installation workflow
Kernel Page Size Fix for Pi 5
If Jellyfin fails to start, check kernel page size with 'getconf PAGE_SIZE'. If it returns 16384 instead of 4096, edit /boot/firmware/config.txt and add 'kernel=kernel8' at the bottom, then reboot. This forces the Pi 5 to use the correct page size.
Default Pi 5 page size
16384 bytes
Required page size
4096 bytes
Kernel page size correction for Jellyfin stability
Media Library Setup & Hardware Acceleration
Create two media libraries: one for movies (content type: movies, folder: /media/movies) and one for TV (content type: shows, folder: /media/tv). Disable hardware acceleration in Dashboard > Playback > Transcoding and set to 'none' because the Pi lacks a usable video encoder.
Accessing Jellyfin
After setup, access Jellyfin at media.local:8096 to sign in with your admin credentials. Add media files to the /media/movies and /media/tv folders via Samba (see next section), then scan libraries in the dashboard to index new content.
Samba Network Sharing
Samba Installation & Configuration
Install Samba with 'sudo apt install -y samba samba-common', then write a configuration file using printf that shares the /mnt/storage/media directory. Set a Samba password with 'sudo smbpasswd -a user', then restart and enable the service.
1
Install Samba: sudo apt install -y samba samba-common
2
Write smb.conf configuration with printf
3
Set Samba password: sudo smbpasswd -a user
4
Restart service: sudo systemctl restart smbd
5
Enable auto-start: sudo systemctl enable smbd
6
Access from Windows or Mac file explorer
Samba network file sharing setup
Windows File Explorer Access
In Windows File Explorer, click the address bar and type '\\media.local\media', then enter your Samba username and password. To make it permanent, right-click This PC, select 'Map network drive', choose a drive letter (e.g., Z), and enter the same path.
Mac Finder Access
In Mac Finder, press Command+K, type 'smb://media.local', select 'Connect as registered user', enter your Samba username and password, then select the media share to mount it like an external drive.
Drag-and-Drop File Management
Once Samba is mounted, you can drag and drop movie and TV files directly into the /media/movies and /media/tv folders from your computer's file explorer, just like any external drive. After adding files, scan libraries in Jellyfin to index them.
Remote Access with Tailscale VPN
Tailscale Installation & Setup
Run the Tailscale install script via curl, then start the client with 'sudo tailscale up'. This will prompt you to authenticate via your browser. Sign in with Google or another account, then disable key expiry in the Tailscale admin console to prevent the connection from expiring after 6 months.
1
Run Tailscale install script via curl
2
Start Tailscale: sudo tailscale up
3
Authenticate in browser with Google account
4
Log into Tailscale admin console
5
Disable key expiry on your Pi device
6
Install Tailscale app on phone from App Store or Play Store
Tailscale VPN remote access setup
How Tailscale Works
Tailscale is a VPN that assigns each device a stable address and allows direct peer-to-peer connections regardless of location. No port forwarding or complex networking is needed; simply log in on multiple devices with the same account to create a private mesh network.
Mobile App Configuration
Download the Tailscale app from the App Store (iOS) or Play Store (Android), log in with the same account used on the Pi, and toggle the VPN on. On iOS, accept the VPN configuration prompt. Once connected, you can access Jellyfin at media.local:8096 and Immich at media.local:2283 from anywhere.
Remote Access Endpoints
When connected to Tailscale VPN, access Jellyfin at media.local:8096 and Immich at media.local:2283 from your phone or any remote device, just as if you were on your home Wi-Fi.
1
Jellyfin
media.local:8096
2
Immich
media.local:2283
Service access URLs on Tailscale VPN
Troubleshooting & Best Practices
Using LLMs for Error Resolution
If errors or unexpected issues occur during setup, use ChatGPT, Claude, or another LLM. Paste the error messages and commands you've run into the LLM, and it will help diagnose and resolve the problem.
Terminal Command History Navigation
Use the up and down arrow keys in the terminal to scroll through previously run commands. This saves time when re-entering commands like SSH after a reboot.
Clear Terminal Display
Run the 'clear' command to wipe the terminal display and reduce clutter. This does not delete previous commands; it only declutters the view.
Curl Command Safety
Be very careful when running curl commands, especially from random internet sources. Always verify what a curl command does before executing it. The Docker and Tailscale install scripts are official and safe, but never blindly paste unknown curl commands.
Documentation Reference
The video description includes a comprehensive written guide with every command in order, with placeholders for username and hostname. Read this carefully and replace placeholders with your actual values to avoid typos.
Worth quoting
"Be very very careful running curl commands. Do not copy paste curl commands from random places on the internet."
— Tucker, at [9:07]
"If you don't do this 6 months from now, you're going to be like, why the hell is everything not working?"
— Tucker, at [19:32]
"Tailscale is basically a VPN that every device you log in gets a stable address and can reach every other device directly no matter where they are."
— Tucker, at [19:32]
Try this
Download Raspberry Pi Imager from raspberrypi.com/software and install Raspberry Pi OS Light on your micro SD card
Assemble the Pi: install heat sink, connect fan, snap case pieces together, and insert micro SD card
Connect Pi to power, Ethernet, and external storage drive
SSH into the Pi and run system updates: sudo apt update && sudo apt full-upgrade -y
Format and mount external drive to /mnt/storage following the drive setup commands
Install Docker and verify with docker run --rm hello-world
Install and configure Immich by downloading docker-compose.yml and .env, editing .env, and running docker compose up -d
Install and configure Jellyfin similarly, and disable hardware acceleration in Dashboard > Playback > Transcoding
Install Samba for network file sharing and set a Samba password
Map the network drive in Windows (Map network drive) or Mac (Finder > Command+K) for easy file access
Install Docker and Tailscale on your Pi, then install Tailscale app on your phone
Disable key expiry in Tailscale admin console to prevent 6-month connection loss
Test remote access by connecting to Jellyfin (media.local:8096) and Immich (media.local:2283) via Tailscale VPN
Implement 3-2-1 backup strategy: keep 3 copies of photos on 2 media types with 1 copy offsite
Made with Glimpse by Wozart
glimpse.wozart.com/v/0ppc3pu3
Share this infographic
Read this infographic as text

Build Your Own Media Server with Raspberry Pi

Summary of the video “How to Replace Your Subscriptions with a Raspberry Pi by Tucker.

Complete guide to setting up a Raspberry Pi as a self-hosted media server running Jellyfin and Immich for photos, movies, and TV shows, accessible remotely via Tailscale VPN.

Hardware Setup & OS Installation

Essential Kit Components

The Canit kit includes a Raspberry Pi 5, 128 GB SD card, case, heat sink, fan, power supply, and USB micro SD card reader. You'll need to separately provide an Ethernet cable and external storage (e.g., 1 TB SSD).

OS Installation Process

Download Raspberry Pi Imager from raspberrypi.com/software, select Pi 5 model, choose Raspberry Pi OS Light, set hostname to 'media pi', create username and password, enable SSH with password authentication, and write to the micro SD card (takes about 10 minutes).

Physical Assembly Steps

Install heat sink on the Pi, connect the fan to the fan port (yellow wire facing outward), snap the Pi into the case bottom piece, align the middle piece, and snap the fan into the top piece. Insert the micro SD card firmly into the slot on the back.

Connectivity & Power

Plug the USB-C power supply into the port marked 'power', connect an Ethernet cable to the Ethernet port and router for stable internet, and plug the external hard drive into a USB port. Warning: the external drive will be erased, so back up any data first.

System Configuration & Storage Setup

SSH Connection & Initial Updates

Connect to the Pi via SSH using 'ssh tucker@media.local' (replace 'tucker' with your username), then run 'sudo apt update && sudo apt full-upgrade -y' to fully update all software. Reboot with 'sudo reboot' and reconnect.

External Drive Formatting & Mounting

List connected devices with 'lsblk', then chain commands to unmount, wipe, create a GPT partition table, build an ext4 filesystem, and mount the drive to /mnt/storage. Add the drive's UUID to /etc/fstab to ensure it persists after reboot.

Directory Ownership & Folder Structure

Change ownership of /mnt/storage to your user with 'sudo chown -r user:user /mnt/storage', then create subdirectories for image and jellyfin (config, cache, media folders). This prevents permission errors when accessing the drive.

Docker & Immich Photo Management

Docker Installation

Run the official Docker install script via curl, add your user to the docker group with 'sudo usermod -a G docker $user', exit and reconnect via SSH, then verify with 'docker run --rm hello-world' and check version with 'docker compose version'.

Immich Setup & Configuration

Create an immich directory, download the docker-compose.yml and .env files from GitHub, edit the .env file to set timezone and other variables, then start with 'docker compose up -d'. Access at media.local:2283 to create a local account and configure photo backup.

3-2-1 Backup Rule for Photos

Keep three total copies of photos on two different types of media with one copy kept offsite. Immich alone is not sufficient as a sole backup; consider keeping an extra drive at a friend's house or performing periodic backups to protect against drive failure or disaster.

Jellyfin Media Server Setup

Jellyfin Installation & Configuration

Create a ~/jellyfin directory, write a docker-compose configuration using printf, create bind mount folders (config and cache), then start with 'docker compose up -d'. Access at media.local:8096 to set language, create an admin user, and configure media libraries for movies and TV.

Kernel Page Size Fix for Pi 5

If Jellyfin fails to start, check kernel page size with 'getconf PAGE_SIZE'. If it returns 16384 instead of 4096, edit /boot/firmware/config.txt and add 'kernel=kernel8' at the bottom, then reboot. This forces the Pi 5 to use the correct page size.

Media Library Setup & Hardware Acceleration

Create two media libraries: one for movies (content type: movies, folder: /media/movies) and one for TV (content type: shows, folder: /media/tv). Disable hardware acceleration in Dashboard > Playback > Transcoding and set to 'none' because the Pi lacks a usable video encoder.

Accessing Jellyfin

After setup, access Jellyfin at media.local:8096 to sign in with your admin credentials. Add media files to the /media/movies and /media/tv folders via Samba (see next section), then scan libraries in the dashboard to index new content.

Samba Network Sharing

Samba Installation & Configuration

Install Samba with 'sudo apt install -y samba samba-common', then write a configuration file using printf that shares the /mnt/storage/media directory. Set a Samba password with 'sudo smbpasswd -a user', then restart and enable the service.

Windows File Explorer Access

In Windows File Explorer, click the address bar and type '\\media.local\media', then enter your Samba username and password. To make it permanent, right-click This PC, select 'Map network drive', choose a drive letter (e.g., Z), and enter the same path.

Mac Finder Access

In Mac Finder, press Command+K, type 'smb://media.local', select 'Connect as registered user', enter your Samba username and password, then select the media share to mount it like an external drive.

Drag-and-Drop File Management

Once Samba is mounted, you can drag and drop movie and TV files directly into the /media/movies and /media/tv folders from your computer's file explorer, just like any external drive. After adding files, scan libraries in Jellyfin to index them.

Remote Access with Tailscale VPN

Tailscale Installation & Setup

Run the Tailscale install script via curl, then start the client with 'sudo tailscale up'. This will prompt you to authenticate via your browser. Sign in with Google or another account, then disable key expiry in the Tailscale admin console to prevent the connection from expiring after 6 months.

How Tailscale Works

Tailscale is a VPN that assigns each device a stable address and allows direct peer-to-peer connections regardless of location. No port forwarding or complex networking is needed; simply log in on multiple devices with the same account to create a private mesh network.

Mobile App Configuration

Download the Tailscale app from the App Store (iOS) or Play Store (Android), log in with the same account used on the Pi, and toggle the VPN on. On iOS, accept the VPN configuration prompt. Once connected, you can access Jellyfin at media.local:8096 and Immich at media.local:2283 from anywhere.

Remote Access Endpoints

When connected to Tailscale VPN, access Jellyfin at media.local:8096 and Immich at media.local:2283 from your phone or any remote device, just as if you were on your home Wi-Fi.

Troubleshooting & Best Practices

Using LLMs for Error Resolution

If errors or unexpected issues occur during setup, use ChatGPT, Claude, or another LLM. Paste the error messages and commands you've run into the LLM, and it will help diagnose and resolve the problem.

Terminal Command History Navigation

Use the up and down arrow keys in the terminal to scroll through previously run commands. This saves time when re-entering commands like SSH after a reboot.

Clear Terminal Display

Run the 'clear' command to wipe the terminal display and reduce clutter. This does not delete previous commands; it only declutters the view.

Curl Command Safety

Be very careful when running curl commands, especially from random internet sources. Always verify what a curl command does before executing it. The Docker and Tailscale install scripts are official and safe, but never blindly paste unknown curl commands.

Documentation Reference

The video description includes a comprehensive written guide with every command in order, with placeholders for username and hostname. Read this carefully and replace placeholders with your actual values to avoid typos.

Notable quotes

Be very very careful running curl commands. Do not copy paste curl commands from random places on the internet. — Tucker
If you don't do this 6 months from now, you're going to be like, why the hell is everything not working? — Tucker
Tailscale is basically a VPN that every device you log in gets a stable address and can reach every other device directly no matter where they are. — Tucker

Action items

  • Download Raspberry Pi Imager from raspberrypi.com/software and install Raspberry Pi OS Light on your micro SD card
  • Assemble the Pi: install heat sink, connect fan, snap case pieces together, and insert micro SD card
  • Connect Pi to power, Ethernet, and external storage drive
  • SSH into the Pi and run system updates: sudo apt update && sudo apt full-upgrade -y
  • Format and mount external drive to /mnt/storage following the drive setup commands
  • Install Docker and verify with docker run --rm hello-world
  • Install and configure Immich by downloading docker-compose.yml and .env, editing .env, and running docker compose up -d
  • Install and configure Jellyfin similarly, and disable hardware acceleration in Dashboard > Playback > Transcoding
  • Install Samba for network file sharing and set a Samba password
  • Map the network drive in Windows (Map network drive) or Mac (Finder > Command+K) for easy file access
  • Install Docker and Tailscale on your Pi, then install Tailscale app on your phone
  • Disable key expiry in Tailscale admin console to prevent 6-month connection loss
  • Test remote access by connecting to Jellyfin (media.local:8096) and Immich (media.local:2283) via Tailscale VPN
  • Implement 3-2-1 backup strategy: keep 3 copies of photos on 2 media types with 1 copy offsite

More like this