coytishost — Jellyfin Media Stack

I wasn’t going to do Jellyfin because I don’t watch TV or movies anywhere near enough to warrant it and homelab people annoy me, and never shut up about it.

This got made because I wanted to watch ted lasso and got carried away, the 8tb HDD was bought for this, I spent 20ish on Apple TV

Eat shit Tim Cook

Full self-hosted media stack running in Docker on an Ubuntu 24.04 LTS VM. Jellyfin handles playback; Sonarr/Radarr automate acquisition; qBittorrent runs behind a WireGuard VPN.


VM Specs (VM 105)

OSUbuntu 24.04 LTS
Resources4GB RAM, 4 cores, 32GB OS disk (NVMe)
Media disk8TB virtual disk (media8tb pool) — mounted at /mnt/media, ~514GB used as of June 2026
DockerCompose-based, files at /opt/media/docker-compose.yml
SSHKey auth

Stack

ContainerPortPurpose
Jellyfin8096Media server — watch.coytis.me
Jellyseerr5055Request portal — request.coytis.me
Sonarr8989TV show automation
Radarr7878Movie automation
Prowlarr9696Indexer manager (synced to Sonarr + Radarr)
SABnzbd8085Usenet downloader
GluetunWireGuard VPN container (Mullvad)
qBittorrent8080Torrent client, routed through Gluetun

qBittorrent shares Gluetun’s network namespace — all torrent traffic exits through the VPN. In Sonarr/Radarr, the download client hostname is gluetun:8080, not qbittorrent.


Directory Structure

/opt/media/          ← Docker Compose + per-container config dirs
/mnt/media/
  tv/                ← TV shows (Sonarr target)
  movies/            ← Movies (Radarr target)
  downloads/         ← SABnzbd/qBittorrent drop zone

Useful Commands

cd /opt/media
 
docker compose ps              # container status
docker compose logs -f         # live logs (all)
docker compose logs -f jellyfin  # live logs (one container)
docker compose restart         # restart all
docker compose pull && docker compose up -d  # update images

Gotchas

  • SABnzbd download paths — must point to /downloads/incomplete (temp) and /downloads (complete) on first run, or it fills the 32GB OS disk
  • qBittorrent hostname — use gluetun:8080 in Sonarr/Radarr, not qbittorrent:8080
  • OS disk — ~35% used after fixing the SABnzbd issue; Docker images live here, keep an eye on it
  • Port 80 — currently blocked by another host on the LAN. Once resolved: open 80 on UFW + router and Caddy picks it up automatically