Building My Homelab

2024-05-18

12 min read

homelab overview
I need to do a better job at cable management. From left to right: an Xbox Series X (unrelated but makes my lab looks better), the app server, and the router. Hanging on the wall is the access point.

Welcome to my homelab adventure! This is my second attempt at creating a homelab. My first try was back in freshman year with a low-end Pentium Gold G5400 PC. I installed Nextcloud on it, ran it with unencrypted HTTP on my campus network (a bold move), and wrote some naive blog posts explaining school concepts in overly complex ways. That was my first home server in a nutshell.

I started hosting tongkl.com (it used to be ktpoint.cn because .com domains cost $70 a year in China) using Hexo, then switched to Hugo. Eventually, I realized I wasn't adding much unique content to the Internet and deleted the blog. For about two years, the apex domain just displayed a stock portfolio performance summary I created as a part of the old blog. Now that I'm back into homelabbing, I still have the itch to share and showcase my achievements. This time, instead of writing how I acquire an HTTPS certificate with certbot on top of 10,000 existing tutorials out there, I'll share tutorials that are hard to find online or things I build that suit my specific needs.

Enough about the past—let's dive into the present! This post is an overview of my homelab. I'll cover my machines, my network architecture, and the services I'm running. Detailed articles on the interesting parts will come later.

The Machines

I don't have a rack because:

  1. I'm a student on a budget.
  2. I might need to move soon.
  3. My apartment doesn't have space for a rack (plus, the Partner Approval Factor for a rack is negative infinity).

Instead, I use mini PCs. They’re compact, powerful enough, and fit my needs perfectly.

I don't quite understand why many on r/homelab insist on buying racks. Why does everyone need multiple 2U servers when a 4-core, 4-thread machine is more than enough for me? But hey, to each their own. I went the mini PC route due to my constraints.

My homelab setup currently includes:

  • App Server: Beelink Mini S12 Pro.
  • Router: Another mini PC with 6 Ethernet ports running Debian.
  • Access Point: UniFi U7-Pro.

The app server, a Beelink Mini S12 Pro, was a birthday gift from my partner (and no, this article is NOT sponsored by Beelink). It features an Intel N100, 16 GB of RAM, a 512 GB SSD from an unknown brand (which I later replaced with a WD Green for better reliability), and a Wi-Fi Ethernet card (useless in my setup though). Despite some complaints online about the machine failing right after the warranty ends, it has been great so far. After some benchmarking, I surprisingly found it achieves <10% less single-core performance than my 8th gen Intel CPU laptop. Kudos to AMD for the competition! This little beast powers all my services, as long as I avoid resource-hungry monsters like GitLab. I run Debian 12 (the latest version at the time of writing) as the host OS for its stability and resource-friendliness.

Almost all my services run as Docker containers, except for Wireguard, which I run natively to connect to my home network via a VPS relay when I'm out. By running containers I don't have to worry about services messing with each other's configurations. I also know they ONLY have access to the folders I give them access to. The only thing they expose is a bunch of ports listening on localhost (nobody is exposing them on 0.0.0.0 and [::], right? Right? Right?). This isolation is such a relief that I'm more than happy to trade a 5-10% performance loss for it. Docker also supports features like Macvlan, which I use for the UniFi Network Application (more on that later). One downside of Docker is its lackluster IPv6 support—it took me two days to figure out the configuration of an IPv6-capable Wireguard container.

I use Docker Engine to run the containers. I've heard good things about Podman, notably its rootless nature, but haven't got a chance to try it yet. High availability isn't necessary for my setup, and I don't have the three machines it typically requires. Running multiple instances on VMs on a single bare metal machine seems pointless. Don't blame me for not learning Kubernetes yet: I have learned it by spinning up a few virtual machines (and found it to be a PITA).

I surely need Proxmox, as virtual machines are a necessity for playing around experimenting. But I refuse to run my containers inside a VM and accept a double performance hit. Fortunately, Proxmox has an official guide on installing PVE on the host machine so that I can run all other services on bare metal alongside virtual machines, not INSIDE them (well, except Home Assistant containers, but more on that later). They happen to only support doing this installation on Debian, which is a good indicator of me choosing the correct OS.

Setting up my homelab was a joyful learning experience, thanks to the awesome-selfhosted GitHub repo and r/selfhosted. But soon I ran into a problem: I needed IPv6 connectivity for private tracker torrenting, but my Verizon FIOS router sucks at IPv6. It can't set IPv6 DNS servers via router advertisement, making Pi-hole useless with IPv6. It also cannot assign ULAs, which is vital to assigning persistent IPv6 addresses to servers. So, I decided to build my own router.

For those wondering, private trackers are usually safe to torrent without a VPN because no publishers can retain an account in those trackers and sue pirating activities at the same time.

Custom Router

I chose to build the router the hard way. I wasn't going to install Opnsense or Mitrotik and call it a day. Instead, I was going to run Debian and use iptables and a bunch of services to act as the router. I bought another N100 mini PC that's even larger in size than the previous server because it has 6 2.5GbE ports. For the access point, I chose the UniFi U7-Pro to be future proof (even though I don't have any Wi-Fi 7-enabled devices). Setting up was tough, but after 2 days of getting complaints about constant disruptions, the router was up and running. It now assigns both GUA and ULA, uses Pi-hole as the DNS server, and has segregated VLANs for future IoT devices. I moved the Wireguard tunnel and Pi-hole to the router, making the first server solely an application server (referred to as the app server going forward).

One thing I didn't mention is HTTPS. I use it for all services. I run certificate renewal on the router and sync the certificates to the application server and my VPS (which hosts the blog you are reading). I prefer not to use a single NGINX reverse proxy for all services and terminate HTTPS at the VPS because I dislike seeing the unsafe icon in my browser when accessing services within my home network. NGINX is my choice of reverse proxy because it's battle-tested and super efficient it's the one I'm the most familiar with.

I've also learned to use Ansible to manage configurations. Suppose my router now dies because the SSD fails. I simply replace the SSD, install Debian, set up SSH keys, and run a single ansible-playbook command. Within 30 minutes it will be up and running as before. No more manual configuration needed. Writing the playbooks was painful, but it's paying off.

Well there's a nuance: I need to download the automatic backup before running the containers because Ansible doesn't handle service data backups. I'll write a separate post for automatic backups.

Network Architecture

My homelab has 4 subnets:

  • Home subnet (192.168.0.0/24, IPv6 GUA, and IPv6 ULA), full access to everything,
  • Guest subnet (192.168.1.0/24), only public Internet access,
  • an IoT v4 subnet (192.168.2.0/24), with no outbound access,
  • an IoT v6 subnet (IPv6 ULA only), with no outbound access.

Some prefer 10.0.0.0/8 to 192.168.0.0/16 for more addresses, but I don't think I'll ever have more than 253 devices in a single subnet. 192.168.x.x sounds like home to me while 10.x.x.x and 172.16.x.x are for malls, schools and enterprises.

I am an advocate for IPv6, but I don't foresee IPv4 disappearing soon, so I am forced to run dual stack for now. But since my IoT devices don't need to interact with the outside world, I make them use IPv6 whenever possible. However, not a lot of IoT devices support IPv6 yet (many manufacturers have it on their agenda but it's always assigned the lowest priority, so you know what will happen). Currently I have 2 IP cameras from Casa and Reolink, neither IPv6 capable. Hopefully things will get better soon so my v6 subnet will have its first user.

I use Unique Local Addresses (ULA) to provide persistent internal addresses of servers over IPv6. IPv6 supports multiple addresses, allowing a subnet to advertise both a GUA prefix (assigned by the ISP) and a ULA prefix (chosen by the admin). Devices can use ULA for internal communication and GUA for external communication, with no NAT involved.

Diagram

Everyone is making a homelab diagram, but since I only have 2 machines, here's my (unsurprisingly simple) diagram.

diagram
Click to see full image

Services

Here are the services I've been using a lot and find super useful:

  • Pi-hole: An essential for blocking ads and trackers.
  • BookStack: I use it as my internal wiki. My partner uses it as a family diary.
  • Jellyfin: Great for streaming... Linux ISOs.
  • Authentik: SSO service, a must-have.
  • Vaultwarden: I never thought a dedicated password manager could make my life so much better.
  • Gitea: My private code repository. Must-have.
  • Uptime Kuma: Every homelabber needs it to get notifications when services are down.
  • Home Assistant: See below.
  • Stirling-PDF: Handy for PDF management.
  • LibreSpeed: To enjoy the satisfaction of a 2.5Gbps network.
  • Frigate: For capturing cat videos.
  • Tiny Tiny RSS + RSS-to-Telegram: A great combo to send homelabbing news, new software versions, and job-seeking notifications to my Telegram account.
  • UniFi Network Application: See below.
  • Syncthing: Keeps folders in sync within seconds.

Here are the services I've used occasionally, and find not that useful:

  • Audiobookshelf: The app is perfect for its use case, but I'm just not that into audiobooks.
  • SnapDrop: Good app, but I don't use it often.
  • MicroBin: I don't really need pastebin in my daily life.
  • Memos: The UX is not smooth, and the developers seem not interested in implementing offline support. They focus on integrating with more Chinese social media platforms... what the heck.
  • NetAlertX: Installed but haven't looked at it yet. Will update this.

Here are the services I find useless:

  • None. Maybe there were some, but I rid them of my servers immediately upon finding them useless.

Home Assistant

Home Assistant is a fantastic piece of software. But I want to talk about its ways of installation.

Home Assistant (referred to as HA going forward) provides four ways of installing:

  1. Install HA Core on bare metal: Limited in terms of third-party service integration since it doesn't support add-ons.
  2. Install HA Core as a docker container: Essentially the same as option 1.
  3. Install HA Supervised on bare metal or inside a VM: Full feature set available.
  4. Install HA OS on bare metal or inside a VM: The most complete installation, with HA Supervisor and HA Core preinstalled on a Linux image.

Since I wanted add-ons, I had to choose between options 3 and 4. I wanted to avoid using a VM if possible, so I tried the challenging route of installing HA Supervised inside an LXC. It was tough because no one had shared any experience on it. The official documentation discourages it and simply marks it as not supported, meaning if you ask questions in the official Discord server, you'll get a shrug and a suggestion to switch to a VM. After two days of Googling and attempting, I gave up. HA Supervised requires very high privileges (like reading dmesg), and I wasn't confident granting an LXC those capabilities. So, I settled for Home Assistant OS inside a VM. It's been working fine, but I still don't like it. I'll get back to this once I gain more relevant knowledge.

UniFi Network Application

Setting up the UniFi Network Application was a breeze compared to Home Assistant since it's just a container. The only problem is that it hardcodes all the ports because it needs to communicate with network hardware. To work around this, I used a Macvlan network to assign it a separate IP.

Future Plans

Here are the things on my backlog. Some require time and effort, others require spare money and/or a bigger apartment.

New Machines

First and foremost, I need a NAS. Right now, I run Jellyfin on my app server and plug a 2TB portable USB drive as the media drive. Sooner or later, I'll need a NAS to hold all my media and my personal Internet archive.

New Services

Once I have enough storage, here are some nice-to-have services.

  • Nextcloud/Seafile: I used Nextcloud for a few years and found it slow for even just a few thousand files. This time, I'll use Seafile for file sharing because it's much much faster. However, Nextcloud does do calendar and contact syncing right. I haven't found anything that matches its user experience for these features, so I might still host a Nextcloud instance, but only for those peripheral features.
  • Web archiving: I want to keep my own Internet archive. I plan to preserve all the pages I visit, especially those behind login, by using browser extensions for snapshots. This way, I can maintain the styles of the sites (something the public Internet Archive struggles with) and perform full-text retrieval on the archive. I also want to host a Wikipedia copy locally.

I’ll be making separate posts for all these interesting things going forward. Stay tuned for more insights and updates on my homelab journey!

Thanks for reading!