Home Server · Docker · Unraid
Every Docker Container Running on My Unraid Server (And What Each One Actually Does)
I ran docker ps on my Unraid server and counted 37 containers. I didn't plan for 37. Nobody plans for 37. Here's the full stack — what each one does, why it's running, and what I'd cut if I absolutely had to.
By Josiah · September 2026 · 14 min read
There's a version of this that starts with me saying I architected this deliberately. That I sat down, drew a diagram, and chose 37 containers as the number I wanted to end up at.
That's not what happened.
What actually happened is that I installed Plex, then realized I needed something to find content for it, then realized that thing needed an indexer manager, then realized the indexer needed a Cloudflare bypass, then — somewhere around container fourteen — I stopped pretending I was going to stop at a reasonable number and just accepted what I was building.
This is the full stack as it exists today: 37 containers, grouped by what they do, with an honest note on each one about why it's there. Some of these are essential. Some are experiments I never deleted. A few I'm running in parallel with each other for reasons that will become clear.
The server this runs on is an i5-13600K with 32GB of DDR4, in a Fractal Design Node 804, running Unraid 7.2.2. If you want the full hardware story, I wrote that up here.
The Media Servers 3 containers
Yes, three. I know. Let me explain before you close the tab.
Plex
The original. Plex is what started all of this. Mature clients on every platform — Apple TV, iOS, Roku, smart TVs, the web — and a UI that people who have never touched a command line can actually use. If you share your library with anyone, Plex is the answer because the client experience is the best in this category, and the people you're sharing with will never need to learn anything new.
Running on port 32400. Hardware transcoding via Intel Quick Sync. Currently serving four regular users.
Jellyfin
Jellyfin is where I ended up after getting tired of Plex's increasingly aggressive push toward cloud features I don't need and a subscription model I don't want. It's fully open source, self-hosted with no required account, and the transcoding quality is excellent. I use Jellyfin as my primary personal client now — I pull it up on my own devices more than Plex.
The honest answer for why both are running: Plex for users, Jellyfin for me. They share the same media directories — no duplication.
EmbyServer
Emby is the third one, and the one I get asked about most. It forked from Jellyfin (or rather, Jellyfin forked from it) and ended up going the Plex route — freemium, with Emby Premiere unlocking features. I'm running it partly to evaluate it against the other two and partly because the audiobook handling is different enough to be worth comparing. It's not my primary server. It might not survive the next round of container cleanup.
I'll write a dedicated comparison when I've spent more time with all three side by side. Short answer: Plex for sharing, Jellyfin for yourself.
The Request Layer 5 containers
This is the piece most people skip when they set up a home server, and it's the piece that makes living with one actually pleasant. Instead of manually searching for content and dropping files into folders, you set up a request interface — users click what they want, a request goes in, and the system handles the rest automatically. The media appears in Plex within minutes.
Seerr
The main request interface. Seerr sits at the front door of the whole media pipeline — users log in, search for a movie or show, hit Request, and the system routes that request to Radarr or Sonarr, which handle finding and downloading it. The UI is clean enough that I've had people use it who have never touched anything self-hosted before.
Seerr_guest
A separate Seerr instance running in guest mode, pointed at the same backends. The reason for two: I can give people a link that doesn't require account creation. Guest mode limits what they can request per day, which is the right balance. People who use it regularly get a proper account on the main instance.
Running on a different port, behind Cloudflare Tunnel. Two separate containers, shared database — keeping them from fighting each other took about an hour of configuration I'm not proud of.
Jellyseerr
Jellyseerr is a fork of Seerr with tighter Jellyfin integration — it syncs watchlists and watch status directly from Jellyfin rather than requiring a separate Plex account. I run it for my own requests so that my Jellyfin watch history informs what shows up as "available" versus "request-able." It talks to the same Sonarr and Radarr as everything else.
seerr-blind-sync
This one is custom — it syncs request state between the main Seerr and the guest Seerr instance so that if something is already requested or available, both instances reflect that. Without it, a guest would see an "available" title as requestable and get confused when nothing happened. It's a small script in a container, and it runs on a cron schedule.
Onboarderr
Onboarderr is an onboarding wizard for new users — it walks someone through creating their Plex account, requesting access to the server, and understanding how the request system works. Solves the "how do I add something I want to watch?" question before it becomes a support ticket in my iMessage.
The *arr Stack 8 containers
If the request layer is the front door, the *arr stack is everything behind it. This is the automation backbone that takes a request and turns it into a file on disk. Each piece has a specific job and they pass work between each other like a pipeline.
Sonarr
TV show management. Sonarr watches for new episodes of shows you're tracking, searches for them through Prowlarr, grabs them via qBittorrent, renames them to a consistent format, and moves them into your library folder. It also upgrades quality — if you grabbed a 720p episode early and a 1080p version comes out, Sonarr will automatically replace it.
Radarr
Same as Sonarr but for movies. The interface is nearly identical. You can set quality profiles — "I want 4K remuxes for everything" or "1080p is fine" — and Radarr will enforce them across your library. Like Sonarr, it upgrades quality automatically when better versions become available.
Prowlarr
Prowlarr is the indexer manager — it's the piece that knows where to look. Instead of configuring indexers in both Sonarr and Radarr separately, you configure them once in Prowlarr and it syncs to everything automatically. When an indexer goes down or needs updated credentials, you fix it in one place. Essential if you're running more than one *arr app.
Bazarr
Bazarr handles subtitles. It watches your Sonarr and Radarr libraries and automatically fetches subtitles from subtitle providers for anything that doesn't have them. I have it set to grab English SDH and a few other languages by default. If you share your server with anyone who uses subtitles, this is non-negotiable.
FlareSolverr
Some indexers protect themselves with Cloudflare's bot-detection. FlareSolverr is a headless browser that sits in front of those indexers and solves the challenges so Prowlarr can get through. You plug the FlareSolverr address into Prowlarr and it handles the rest. Invisible when it's working, immediately obvious when it's not.
Unpackerr
A lot of downloaded content arrives as compressed archives — .rar files, sometimes nested several levels deep. Unpackerr watches the download folders and extracts them automatically when Sonarr or Radarr marks a download as complete. Without it, your *arr apps see a .rar file where they expect a .mkv and nothing imports correctly.
Agregarr
Agregarr aggregates content feeds and manages watchlists across the *arr ecosystem — pulling in lists from Trakt, IMDb, and other sources and syncing them to Radarr and Sonarr as monitored items. It's how I keep up with "must-watch" lists without manually adding things one at a time.
Dispatcharr
Dispatcharr handles routing and task dispatch within the stack — think of it as a coordinator that makes sure the right app gets the right task at the right time. It's newer and I'm still figuring out the full extent of what it can do, but it's replaced some manual Sonarr/Radarr interaction I used to do by hand.
Download Clients 2 containers
binhex-qbittorrentvpn
The main download client. This is binhex's qBittorrent image with a VPN built in — the container routes all traffic through the VPN before it hits the internet, and if the VPN connection drops, the container stops downloading rather than exposing your real IP. The VPN is always-on, always verified. Sonarr and Radarr talk to this container to queue downloads.
The VPN kill-switch is the reason to use binhex's image specifically rather than plain qBittorrent. The network namespace approach means there's no configuration error that could leave you unprotected.
binhex-qbittorrent-audiobooks
A separate qBittorrent instance dedicated to audiobooks. The reason for the split is that audiobook sources and settings are different from everything else — different categories, different speed limits, different completion paths. Keeping it separate means I can tune it independently without touching the main download client config.
Audio, Books, and YouTube 3 containers
Audiobookshelf
Audiobookshelf is a self-hosted audiobook and podcast server. It remembers your position across devices, has good iOS and Android apps, and handles the metadata for audiobooks way better than anything else I've tried. If you have an audiobook collection and you're not running Audiobookshelf, you're making your life harder than it needs to be.
ReadMeABook
Another audiobook interface, running alongside Audiobookshelf. Where Audiobookshelf is the polished client app, ReadMeABook handles some edge cases around format conversion and chapter management that Audiobookshelf doesn't cover as cleanly. Currently evaluating whether both need to stay long-term.
Youtarr
Youtarr is a YouTube archiving tool — you point it at channels or playlists and it downloads them locally and keeps them updated. I use it for channels I follow that post things I want to be able to watch offline or that have a history of disappearing. It runs yt-dlp under the hood with a web UI on top.
Tracking and Stats 1 container
Tautulli
Tautulli is a statistics and notification layer for Plex. It tracks who's watching what, when, how long, on what device, at what quality — and it can send notifications for any of it. I have it set up to message me on Telegram when someone starts a stream, when a transcode is running (and what resolution), and when a new episode of a monitored show gets added to the library. It's the piece that makes the whole system feel alive rather than just running in the background quietly.
I'm writing a dedicated Tautulli article covering the full notification setup — the Telegram integration specifically is worth its own post.
Home Automation 3 containers
This is where the server stops being just a media machine and starts being the hub for the house.
Home Assistant
Home Assistant is the brain. Smart plugs, smart bulbs, cameras, the Eufy doorbell, the Apple TV — everything that's "smart" in the house runs through or talks to Home Assistant. I have automations for lights, notifications when the cameras detect motion, and a Telegram integration that lets me check on the house remotely. The learning curve is real, but there's nothing else that comes close to what it can do once you've spent the time configuring it.
The smart plug on the server tower itself is wired through Home Assistant, which means I can power-cycle the whole machine remotely if something goes sideways. That's either very clever or a terrible idea — I haven't decided.
Mosquitto
Mosquitto is an MQTT broker — it's the message bus that IoT devices use to talk to each other. A lot of smart home devices speak MQTT natively; instead of each device cloud-calling home, they publish messages to Mosquitto and Home Assistant subscribes to them locally. No cloud dependency, faster response times, and your device data stays on your network.
Scrypted
Scrypted bridges cameras and smart home devices to Apple HomeKit, Google Home, and Home Assistant simultaneously. It's the piece that lets my Reolink and Eufy cameras show up as proper HomeKit cameras — with actual HomeKit Secure Video if I wanted it — while also feeding into Frigate for AI detection and Home Assistant for automations. It translates between different camera protocols so everything speaks the same language.
Security Cameras 2 containers
Frigate
Frigate is an NVR — a network video recorder — with AI object detection built in. It watches camera feeds in real time and identifies people, vehicles, animals, and other objects, triggering events when it sees something relevant. The key difference from cloud camera systems is that the AI runs locally, on your hardware, and the video never leaves your network. I have it monitoring the exterior cameras and piping events into Home Assistant for automations.
Frigate's real advantage is latency and privacy. Cloud cameras send video offsite to run detection. Frigate does it on the server in milliseconds. A Coral TPU accelerator would make it even faster, but the i5-13600K's iGPU handles it well enough at current camera count.
eufy-security-ws
eufy-security-ws is a WebSocket bridge that connects Eufy cameras to Home Assistant without requiring Eufy's cloud. Eufy's native integration routes everything through their servers, which is both a privacy issue and a latency issue. This container runs locally, talks directly to the Eufy homebase on the same network, and exposes events to Home Assistant with no cloud hop in the middle.
Notifications 1 container
Apprise API
Apprise is a notification aggregator — one API endpoint that can push to Telegram, email, Slack, Discord, Pushover, ntfy, and about 80 other services. Instead of each container knowing how to talk to Telegram directly, they send to Apprise and Apprise handles routing. It means if I ever change notification services, I update Apprise once and nothing else breaks. Tautulli, Home Assistant, Frigate, and Sonarr all route their notifications through it.
Infrastructure 6 containers
CloudflaredTunnel
This is how everything on the server is accessible from outside the house without opening a single port on the router. Cloudflare Tunnel creates an outbound connection from the server to Cloudflare's network, and then Cloudflare routes external requests through that tunnel. Zero port forwarding, no exposed public IP, and Cloudflare handles SSL automatically. It's one of the best "set it and forget it" pieces of the whole stack.
MariaDB
MariaDB is the database that several containers share — Seerr, some Home Assistant integrations, and a few others store their data here rather than in SQLite files. Running a shared database container is slightly more complexity upfront but makes backups simpler: one database container to back up instead of SQLite files scattered across a dozen container directories.
Tunarr
Tunarr creates virtual live TV channels from your media library. You build a schedule — Thursday nights are The Office, Friday evenings are a movie marathon — and Tunarr streams it as an IPTV channel that any app supporting live TV can tune into. It sounds like a novelty but it's actually a different way of watching that I come back to more than I expected to.
UptimeKuma
UptimeKuma is a self-hosted uptime monitor. It checks that every service on the server is responding — Plex, Jellyfin, Seerr, Home Assistant, all of them — on whatever interval I set, and notifies me if something goes down. The dashboard gives a real-time view of the whole stack's health. I have it set to ping me on Telegram within two minutes of any service going offline.
Homepage
Homepage is a customizable dashboard that shows everything running on the server — container status, library stats from Plex and Jellyfin, current downloads, Sonarr and Radarr queues, system resource usage, and weather. It's the first thing I open when I check on the server. You configure it with YAML files, which means it's actually maintainable once you learn the format.
CloudCommander
CloudCommander is a web-based file manager. When I need to move files around on the server without SSH-ing in or opening a terminal, CloudCommander gives me a browser-based two-pane file manager that works well enough for quick operations. Not something I use daily, but the times I need it, I'm glad it's there.
Custom Containers 3 containers
kvmedia-static
An nginx container serving the KVMedia website locally on ports 80 and 443. Yes, the site you're reading right now is deployed on Cloudflare Pages — but I run a local copy for development and testing. When I'm building something new and want to see how it renders before pushing it live, this is where that happens. The SSL certificates are locally signed; nginx serves the same directory the production build deploys from.
poster-cache
A caching layer for movie and TV show poster images. When Plex or Jellyfin requests artwork, it hits the cache first — so if three people open the library at once, the poster server isn't making three identical outbound requests. On a fast local network this is a marginal win; it matters more when bandwidth is constrained or when clients are connecting over the Cloudflare tunnel.
plex-cache
A Python caching script running as a container — it pre-fetches Plex metadata and artwork for recently-added titles so the first time someone browses to a new section it loads fast rather than triggering on-demand fetching. Part of the same caching strategy as poster-cache but specific to Plex's API format.
How It All Connects
The thing that makes this feel like a system rather than a pile of containers is how they talk to each other. When someone requests a movie through Seerr, that request goes to Radarr, which asks Prowlarr to search its indexers (FlareSolverr handles any that are Cloudflare-protected), which hands a result to qBittorrent to download, which Unpackerr extracts if needed, which Radarr imports and renames, which Plex and Jellyfin both pick up via library scans, after which Tautulli will notify me when the first person plays it.
That whole chain runs without me touching anything. I get a Telegram message when the request comes in and another one when it's available. Start to finish, for most titles, under twenty minutes.
The home automation side is its own parallel system: cameras feed into Frigate for object detection, events go to Home Assistant, Home Assistant decides whether to send a notification through Apprise to Telegram. The smart plug on the server tower is wired into that same Home Assistant instance, which means theoretically I can power-cycle the server that's running Home Assistant from Home Assistant itself. I'm choosing not to think too hard about that one.
What I'd cut if I had to: Emby goes first — I haven't needed it alongside Plex and Jellyfin, it was always an experiment. ReadMeABook is probably redundant now that Audiobookshelf has matured. CloudCommander is a nice-to-have I could replace with SSH when needed. That gets me from 37 to 34, which is somehow still not a short list.
The rest of these articles will go deeper on the pieces worth understanding in detail: the Tautulli + Telegram notification setup, how Frigate and Home Assistant work together for camera automations, the full backup strategy (because 37 containers of configuration is a lot to lose), and what iOS apps I'm using to tie everything together when I'm away from home.
If you're just getting started and you want to know which of these to install first: Sonarr, Radarr, Prowlarr, and one media server is the core. Everything else builds from there, and none of it was a bad idea at the time I added it.
Disclosure: Some links on this page may be affiliate links. I built this server with my own money; nobody is paying me to recommend any of this software. All of the containers listed are free and open source — there's nothing here I'm promoting for a commercial reason.
— Josiah
37 containers and still hasn't touched the docker compose file I wrote six months ago.