Home Media Server

Your own personal streaming service. Netflix, but you're in charge.

A note on legality: This guide covers tools commonly used for managing personal media libraries. Some of these tools can be used in ways that may not comply with copyright law in your jurisdiction. This content is provided for educational purposes. What you do with this information is your own responsibility.

What is a home media server?

A home media server is a computer (or even a Raspberry Pi) that stores your media -- movies, TV shows, music, books -- and streams it to any device in your house. Your phone, your TV, your tablet, a friend's laptop. It's like running your own private streaming service.

You open an app that looks and feels like Netflix. You browse your library, pick something, and hit play. It streams from your server to your device. That's it.

But the really interesting part isn't the streaming -- it's the automation. The Linux homelab community has built an incredible ecosystem of tools that work together to automatically find, download, organize, rename, and serve your media. You tell the system what you want, and it handles the rest.

The big picture

There are a lot of moving parts in a fully automated media server. Here's how they all fit together:

┌─────────────────────────────────────────────────┐
│           Overseerr / Jellyseerr                │
│         (request movies & TV shows)             │
└──────────────────┬──────────────────────────────┘
                   │ sends requests to
                   ▼
┌─────────────────────────────────────────────────┐
│          Sonarr / Radarr / Lidarr               │
│       (media management & automation)           │
└──────────┬──────────────────┬────────────────────┘
           │ searches          │ sends downloads to
           ▼                   ▼
┌──────────────────┐  ┌──────────────────────────┐
│    Prowlarr       │  │  SABnzbd / qBittorrent   │
│   (indexers)      │  │   (download clients)     │
└──────────────────┘  └──────────┬───────────────┘
                                 │ completed files
                                 ▼
                      ┌──────────────────────────┐
                      │    Plex / Jellyfin        │
                      │   (media server / UI)     │
                      └──────────────────────────┘

Don't worry if this looks like a lot. Each piece has a specific job, and we'll walk through every one of them. Here's the short version:

You don't need all of this. You can start with just Plex/Jellyfin and manually add files. Then add Sonarr when you're ready to automate TV shows. Then Radarr for movies. Build it up over time -- there's no rush to set up the entire stack on day one.

Plex vs Jellyfin

The first decision you'll make is which media server software to use. There are two main options, and both are excellent.

Plex

Plex is the most popular media server. It's polished, well-supported, and has apps on virtually every platform -- smart TVs, Roku, Apple TV, Fire Stick, iOS, Android, web browsers, game consoles.

Jellyfin

Jellyfin is the fully open-source alternative. No accounts, no subscriptions, no ads, no telemetry. Everything runs on your server and stays on your server.

Which one should you pick? If you want the most polished experience with the widest device support, go with Plex. If you value open source, privacy, and not depending on a company's servers, go with Jellyfin. Both work great with the rest of the stack described in this guide series.

Docker: how you'll run everything

Almost every app in this guide runs in Docker. If you haven't used Docker before, here's the quick version: Docker lets you run applications in isolated containers. Each app gets its own little environment with exactly what it needs, and they don't interfere with each other.

Think of it like running each app in its own tiny virtual machine, except way lighter and faster.

Why Docker?

Installing Docker

On most distros, you can install Docker and Docker Compose with your package manager:

# Ubuntu / Debian / Mint
sudo apt install docker.io docker-compose-v2

# Fedora
sudo dnf install docker docker-compose

# Arch
sudo pacman -S docker docker-compose

Then add your user to the docker group so you don't need sudo every time:

sudo usermod -aG docker $USER

Log out and back in for the group change to take effect. Verify it works:

docker run hello-world

Docker Compose basics

Docker Compose lets you define multiple containers in a single YAML file. Instead of running long docker run commands, you write a docker-compose.yml file and run docker compose up -d to start everything.

Here's a minimal example that runs Jellyfin:

services:
  jellyfin:
    image: jellyfin/jellyfin:latest
    container_name: jellyfin
    ports:
      - "8096:8096"
    volumes:
      - ./jellyfin/config:/config
      - /path/to/your/media:/media
    restart: unless-stopped

Key concepts:

Common commands (for a full breakdown of every docker flag, check out wtflag.wtf):

# Start all containers in the background
docker compose up -d

# Stop everything
docker compose down

# View logs
docker compose logs -f

# Update all containers to latest versions
docker compose pull && docker compose up -d

# Restart a specific container
docker compose restart jellyfin

Setting up Plex

Add this to your docker-compose.yml:

services:
  plex:
    image: lscr.io/linuxserver/plex:latest
    container_name: plex
    network_mode: host
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/New_York
      - VERSION=docker
    volumes:
      - ./plex/config:/config
      - /data/media/movies:/movies
      - /data/media/tv:/tv
      - /data/media/music:/music
    restart: unless-stopped

Start it with docker compose up -d, then open http://your-server-ip:32400/web in a browser. You'll be walked through initial setup -- sign in with your Plex account, name your server, and point it at your media folders.

PUID and PGID: These tell the container to run as your user instead of root. Run id in your terminal to find your user ID and group ID. This prevents permission issues with your media files.

Setting up Jellyfin

Add this to your docker-compose.yml:

services:
  jellyfin:
    image: jellyfin/jellyfin:latest
    container_name: jellyfin
    ports:
      - "8096:8096"
    volumes:
      - ./jellyfin/config:/config
      - ./jellyfin/cache:/cache
      - /data/media/movies:/movies
      - /data/media/tv:/tv
      - /data/media/music:/music
    restart: unless-stopped

Start it with docker compose up -d, then visit http://your-server-ip:8096. Create your admin account, add your media libraries, and you're done. No external accounts needed.

Hardware transcoding

If you want your server to convert video formats on the fly (so older devices can play newer formats), you'll want hardware transcoding. This uses your CPU's or GPU's built-in video encoder instead of doing it in software (which is painfully slow).

For Intel CPUs with Quick Sync (most Intel CPUs from the last decade), add this to your container:

    devices:
      - /dev/dri:/dev/dri

For NVIDIA GPUs, you'll need the NVIDIA Container Toolkit installed, then add:

    runtime: nvidia
    environment:
      - NVIDIA_VISIBLE_DEVICES=all

Jellyfin gives you hardware transcoding for free. Plex requires Plex Pass.

File organization

How you organize your media files matters. Both Plex and Jellyfin (and the arr apps) expect a specific folder structure to properly identify and match your content.

Recommended structure

/data/media/
├── movies/
│   ├── The Matrix (1999)/
│   │   └── The Matrix (1999).mkv
│   ├── Inception (2010)/
│   │   └── Inception (2010).mkv
│   └── ...
├── tv/
│   ├── Breaking Bad/
│   │   ├── Season 01/
│   │   │   ├── Breaking Bad - S01E01 - Pilot.mkv
│   │   │   ├── Breaking Bad - S01E02 - Cat's in the Bag.mkv
│   │   │   └── ...
│   │   ├── Season 02/
│   │   └── ...
│   └── ...
├── music/
│   ├── Artist Name/
│   │   ├── Album Name (Year)/
│   │   │   ├── 01 - Track Name.flac
│   │   │   └── ...
│   │   └── ...
│   └── ...
└── books/
    ├── Author Name/
    │   ├── Book Title/
    │   │   └── Book Title.epub
    │   └── ...
    └── ...
Don't stress about naming. If you're using Sonarr and Radarr, they handle renaming and organizing automatically. You just tell them where to put things and they take care of the rest. The structure above is what they'll create for you.

The hardlinks trick

One important concept: when the arr apps "import" a downloaded file, they can either copy it or create a hardlink. A hardlink is like having the same file in two places without using double the disk space. The download client sees the file in its download folder, and Plex sees it in the media folder, but it's only stored once on disk.

For hardlinks to work, your downloads folder and your media folder need to be on the same filesystem. A common setup:

/data/
├── downloads/
│   ├── complete/
│   └── incomplete/
└── media/
    ├── movies/
    ├── tv/
    └── music/

Then in Docker, mount the entire /data directory so all containers can see both downloads and media:

    volumes:
      - /data:/data

The guide series

This guide is the overview. The rest of the series dives deep into each component:

  1. Home Media Server -- You are here. The big picture, Plex/Jellyfin setup, Docker basics.
  2. The *Arr Stack -- Sonarr, Radarr, Lidarr, Readarr, Prowlarr, and Bazarr. The automation layer.
  3. Download Clients -- Usenet (SABnzbd, NZBGet) and torrents (qBittorrent). How to actually acquire media.
  4. Indexers -- How the arr apps find content. Usenet indexers, torrent trackers, and Prowlarr.
  5. Overseerr & Jellyseerr -- The request system. Let friends and family request content through a beautiful UI.

Start with this page to get your media server running, then work through the rest as you're ready. Each guide builds on the previous one, but you can also jump to whichever part interests you most.

Hardware recommendations

You don't need a beastly server. Here's what works at different levels:

Just getting started

More serious setup

Going all out

Start small. An old laptop with a USB hard drive is enough to run this entire stack. You can always upgrade later once you know what you need. Most people start with "I'll just try Plex" and end up with a rack in their closet within a year.

Which Linux distro?

For a media server, you want something stable and low-maintenance. Popular choices:

If you're already running a Linux desktop, you can run the entire stack right on that machine too. Docker doesn't care what distro you're on.

Next steps

You've got the overview. Your media server (Plex or Jellyfin) is running. Now it's time to automate. Head to the *Arr Stack guide to set up Sonarr, Radarr, and the rest of the automation layer.