The current stack

While I explained how I got to this point, I'd also like to take a moment to fully explain the software stack that I run as of now. All of this runs on a single Dell Poweredge R740 with a dedicated entry-level Intel GPU for hardware accelerated tasks. Using LACP bonds, my server has 3 links to my network which allows for any two of them to go down before the server loses network connection. Two UPS units provide surge protection, power filtering, and a battery backup to the blade and networking equipment. With the exception of my unfortunately located ONT, the entire chain has this power backup. If I can get a third UPS for the ONT, I will be able to throw the main breaker to my house and my server would still run and have network connection for 10-20 minutes.

Now let's get to the fun part...

The software!

First things first, Ubuntu from the old Framework won't cut it. From the beginning, my blade runs the most up-to-date version of Proxmox VE. The 8 500gb SSDs the server came with are in a zfs2 pool with the lion's share of storage going to my main VM. Speaking of... VMs! I have three so far: my main Ubuntu VM which runs all my Docker containers, a dedicated HomeAssistant VM because that's how it "prefers" to run, and a smaller VM for a friend of mine to use as a game server. The latter is set to tag all outbound traffic on a unique VLAN. Combined with the Wireguard server I spun up for my friend, they can remote in and manage their server or use their Dockhand dashboard without being able to see my server or personal network devices.

The real meat and potatoes of my homelab comes down to the mixture of Docker containers I run. I run containers for Jellyfin, Jellyseerr, media management, automated transcoding and remuxing, photo backups, media uploading, password management, data visualization, LoRA radio management, and more. Here's the full list of what I run:

  • Copyparty (for quick file management)
  • Dockhand (to manage other Docker containers and stacks)
  • Filebrowser (to offer Google Drive-like file uploading and sharing for unique circumstances)
  • Ghost (to host my blog. You're seeing it right now!)
  • Grafana (to show past and present user statistics for my Resonite headless servers)
  • Immich (to replace Google Photos / iCloud for automated photo and video backups)
  • Inspircd (to self-host an IRC server. Currently not running because configuring it will require a lot of research)
  • Jellyfin (perhaps the crown jewel of my homelab. It functions as my media streaming server that I've poured the most time and effort into for the sake of reliability and uptime)
  • Jellyseerr (A sidecar site that allows JF users to request new media on a web portal)
  • Meshmonitor (to connect to my attic-mounted Meshtastic radio to offer LoRA mesh monitoring, communication, and packet visualization)
  • Nginx Proxy Manager (a fancier webui replacement for swag. It handles my reverse proxy and automated certificate renewals)
  • Pumpkin (a minecraft server software I experiment with which is written in Rust and touts great efficiency and speed although it is still in development and isn't fully featured)
  • Resonite Headless (to host my Resonite headless, specifically voxelbonecloud's branch)
  • Samba (simple server to browse my server's files from my PC's file browser)
  • Scrutiny (a utility container which monitors the health of my spinning hard drives)
  • Tdarr (my automated transcoding stack which standardizes the incoming media to ensure a smooth viewing experience and save data on my server via visually lossless compression)
  • Vaultwarden (A Rust re-implementation of the Bitwarden server meant to run more performantly)
  • Zipline (to provide file uploads and link shortening, the latter of which being ironic with how long my main domain is)

Out of all the containers I've listed above, there are a few which stand out to me and have gotten the most love:

Dockhand

Ever since I burned myself with Portainer, I've been a happy user of Dockhand. The one issue I had with it (the inability to attach to running containers) was fixed! I'd highly recommend this for anyone who wishes to run a small to medium sized homelab. The only other thing I'd mention is to leverage the power of stacks. It allows you to write pure compose files and combine multiple containers into one stack, allowing you to organize your containers easier. It's actively developed and even has a party trick up its sleeve: by running a companion container on a different machine, you can add it as an environment and manage its docker containers from the main server and see all your containers across multiple machines in one spot.

Tdarr

This plays an important role in my media server content stack. "Acquired" content can be in many different containers, and codecs, contain many audio and subtitle tracks, or have any other combination of things that may make playback a bit more involved. Using the main Jellyfin apps or clients is no problem, as they handshake with the server ahead of time and negotiate what the client's capabilities are and decides if remuxing or transcoding is needed before the stream begins, but some other environments aren't so lucky; namely VRChat. Jellyfin allows you to copy a link to the direct video file to share with others without an account. These links can be inserted into VRChat video players and play ingame...if the codecs are right. On top of this, you cannot select between audio tracks or use subtitle tracks present in the file. For things like anime, this means that you must make sure VRChat picks the dubbed audio track or else the Japanese audio will be nonsensical without the ability to show the subtitles (unless you know Japanese which I do not). I ultimately settled on using AV1 for the video codec and AAC for the audio codec as, through trial and error, I found that VRChat liked these both. The only wrinkle is that you need to install the AV1 codec for free from the Microsoft store before the videos load in VRChat. If you're on Linux? I have no idea.

So that's the play then. I set up my automated transcoding library with these parameters, add some checks to make sure it skips files that are in the right format, and set it on its way. The few files I test with it work fine. Subtitles are in the right order, audio stream defaults work, the filesize usually goes down which is always a plus. I set it loose on my entire couple-tb library and employ the help of both my PC and laptop to hurry it along. Smooth sailing until I get a Telegram message from one of my regular users. Loki is purple. I don't think that's supposed to happen?

A screenshot of a close-up of Loki from the first episode in which the color space is off, making him look tinted purple
That isn't right. Shiiiiiiiiiiii-

Through plenty of trial and error, I found the culprit: Dolby Vision. Dolby Vision is a special kind of HDR spec which does a bit more than your bog-standard HDR10 goodness. Dolby Vision is able to change the color space and other properties of the video on a scene-by-scene basis whereas HDR10 is limited to just one set of metadata for the entire video. When my transcoding workflow processed the file, it correctly picked up the HDR metadata, but it completely dumped all Dolby Vision metadata which led to Loki turning purple. Unfortunately, AV1 support with Dolby Vision does exist, but requires compiling Handbrake with special flags and other fun that tdarr didn't support. A community made (and probably vibe coded >.>) fork by DeNiX is available to allow for proper Dolby Vision transcoding support, but it only went to HEVC. I figured this was an ample compromise. This unfortunately leads to a situation where there are some HEVC landmines in my library that won't load in VRChat unless you have the $0.99 HEVC codec from Microsoft, but I will ultimately migrate to entirely AV1 when possible to fully standardize my library.

After all that, I can just let tdarr loose on my entire library. It has the added benefit of scanning the video files for corruption, something that helps me fix my library before my users discover broken files and need to wait for me to fix them. While not being FOSS, tdarr is an absolutely indispensable part of my Jellyfin stack and something that I find extremely useful. I'm not even leveraging its full feature set, as the transcoding workflows can get a lot more fancy! You simply assemble a workflow in a diagram and use nodes to manipulate your video file as it goes through the pipeline and branches out depending on the results from each step.

Immich

While one of the newer additions to my homelab, I am extremely satisfied with the quality of Immich's underlying tech and lovely frontend (which, let's be honest, is a 1:1 ripoff of Google Photos). I usually find that self hosting introduces compromises compared to cloud solutions, and while that's the case here, it easily is the most seamless experience I host on my server. I am able to use it and forget that it's running on a server locally at home. A few features also really surprise me with how advanced they are! For example, smart search is extremely useful and works like magic even though it runs on an entry-level GPU. Here's an example:

Immich web ui with a search for "a bear animatronic in a virtual scene in utter dismay that he just lost a game of chess". The first result is a VRChat screenshot of Glamrock Freddy losing a game of chess.
This is just magic to me with how underpowered the GPU is!

While smart search is my favorite ML feature, Immich can also use ML-powered OCR and face detection to group photos by the people in them. Such features would feel strange to use with a cloud provider. Would you give Google the names and faces of all your friends and family? Because I self host, I know the buck stops with me.

Unfortunately, it isn't all sunshine and rainbows, but fortunately, the nitpicks aren't that bad. The main issue I have is the lack of detailed reverse geocoding. Reverse geocoding is the act of taking GPS coordinates and returning useful information such as the city, state, or country. Detailed reverse geocoding can get even more refined and return individual street addresses. While Google Photos can do this, Immich can only get as detailed as the city a photo was taken in. An update to their reverse geocoding which will allow for address-level specificity is on their roadmap. ETA Soon™️. The only other small gripes I have are quite small indeed. For example, the search bar must specifically be instructed on if you're using smart search, searching a location, or for a person's face. A future update will hopefully allow Immich to just "know" what kind of thing you're searching for and offer autocomplete suggestions accordingly. Additionally, it's a little easy to create "orphaned" assets which exist on my local phone's storage / iCloud which have been deleted on Immich. Google Photos was able to solve these discrepancies. I hope Immich can with an update.

Jellyfin

Saving the best for last! Jellyfin is only beat out by Resonite headlesses for how long they've spent in my homelab setup. I very much derive enjoyment from helping others. I can't offer my Immich to friends due to not wanting to worry about losing their data and I can't offer my password manager server because...well... don't give me your passwords even if they're encrypted. But then there's Jellyfin! I can host my own little Netflix and let my friends connect and use it. Along with the Jellyfin instance itself, I set up a reverse proxy with automatic SSL certificate renewal. I even set up some custom CSS to modernize the look and even made my own custom branding!

The shape of the Jellyfin logo with a photo of my dragon smiling laid under it. "Kodufin" in the Jellyfin font is next to it.
Quite proud of how good it turned out!

Most setups you'll see on r/Jellyfin or r/JellyfinCommunity will use some method of VPN like Wireguard or Tailscale. This wouldn't do for me as I wanted it to function as seamlessly as any other streaming service, and that's what I've got! Every once in a while, I check up on the server usage data to see how many people are using it, and it does make me legitimately happy to see my friends find my server useful. I haven't fished for compliments with my server, so I haven't gotten much feedback, however I do have this one quote from one of my users which made me feel amazing:

[...] I really like the skin you have on yours. It's also the most reliable I have access to which is really nice

My current storage setup relies on an external enclosure with a couple 3.5" 4tb hard drives, but while drive parity is optional with media libraries as the worst that'll happen is an inconvenience, I'd love to simplify my library and utilize the other 8 2.5" bays in my server.

iDRAC 9 Screenshot of the front of the Dell server with the first 8 out of 16 drive bays filled and the last 8 empty.
8 drive bays just waiting to be filled...

Unfortunately, the smaller 2.5" form factor limits the drive sizes I can look after. It seems the Seagate BarraCuda ST5000LM000 is my goto, with 5 whole terry-bytes of storage. Multiply that by 8 for an eye watering 40tb of raw storage. Slap a zfs2 pool on top for dual parity and that is about ~32tb of usable storage. Not bad! Especially considering the fact my current library weighs in at "only" 3.941tb. Only one small problem... Drives are expensive! Thanks, Sam Altman. Bubble can't pop fast enough. These drives are sold new for a ~cool~ $250. They can be found on eBay for around $120-$150. Just have to be willing to play the eBay lottery. I am more willing to do so given the zfs2 pool allowing for additional redundancy. That is for down the road though when I actually have money! Or our economy explodes. Let's see what happens first.

Why bother with this?

Because it's fun! I view homelab projects not simply as a set of obstacles I must slog through, but a fun project from beginning to end. I know that people who similarly enjoy homelabbing are quick to recommend it, but not everyone views it through the same lens. Some people want things that "just work", but I am more than welcome to get metaphorically "down and dirty" to end up with a nice end product that both myself and my friends can find useful. A homelab will never be done. I always feel like I am working on something else, and finishing a project never ends with a sense of relief (although that is experienced), but rather immediately pivots to "what now".

I must also be thankful, as even with these ridiculous AI-induced prices, this hobby is relatively "cheap". I could have gotten into project cars or firearms. Thank god I picked something more """affordable""".