My Self Hosted setup in 2025

The hardware and software that I am using an how.

My setup at home is less about constant revolution and more about steady evolution these days. Unlike the frantic pace of change that I had in previous years, it has settled into a phase of gradual improvement, focusing mostly on stability. Everything is accessed via VPN only. This approach stems from a lot of iterations to find the right ‘fit’ for me and limited time available to dedicate to the setup, general satisfaction with the current capabilities, and having enough resources now to conduct tests without making breaking changes.

In this article, I’ll walk through the hardware and software powering my setup. I plan to delve into more specific configuration details in future posts as needed.

The Hardware

In my previous article, I explained why I started self-hosting. That journey led me to acquire different types of hardware for various purposes, often without a grand design in mind, and there’s still none today, haha! I also try to focus on cheap, unused, or second-hand items for my setup whenever possible.

My homelab in 2023

The Compute

I’m still using an old Sony Vaio laptop (they used to make great devices!) as one of my compute nodes. Years ago, I upgraded the RAM to 12GB of DDR3 and replaced the HDD with an SSD. This keeps it a decent machine, and the battery somehow still holds two or three hours after more than a decade, maybe that 80% charge limit protection actually worked! The screen backlight no longer works, meaning reinstalls require a flashlight assist to read the display. Recently, I added a USB-to-Ethernet dongle for a second 1 Gbps port. While the Intel Core i5 3rd Gen isn’t the fastest anymore, it’s capable enough for what I need and runs multiple containers and VM at once without too much sweat.

Additionally, I snagged two Dell Optiplex machines from Facebook Marketplace: one SFF (Small Form Factor) and one uSFF (Ultra Small Form Factor), both with 4th Gen Intel Core i5 processors. For my Opnsense router (the SFF model), I added an Intel X520 NIC to get a 10 Gbps connection from my ISP modem and down to my managed switch. The uSFF node, used as a Proxmox host, got a second NIC using a USB-to-Ethernet dongle; I’ll explain how I use both NICs later. They are serving me well, each upgraded with 16GB of DDR3 RAM and a SATA SSD. Even with these older CPUs (released in 2014), I haven’t seen significant load issues for my typical usage.

However, I started noticing heat issues, and the power draw became higher than I liked as the load increased. Plus, more compact options are readily available now. I managed to get two Beelink EQR5 mini PCs with AMD processors and dual 1 Gbps NICs (built-in is definitely nicer than dongles). These were reasonably priced in Canada during Black Friday. A key benefit was the increased RAM capacity: 32GB DDR4 each, compared to the older laptop and Dell machines; memory was becoming a bottleneck with the number of services running continuously. These new devices are also much better with space and heat management without drawing excessive power. I might even consider getting another one if the price is right or refurbished.

I also have a Raspberry Pi 4 with 4GB that has served many purposes. It now acts as a compute node for management tasks, with an SSD connected via a USB-to-SATA cable in a 3D-printed case.

I am now using my main PC tower for making tests and run some local AI inference. It has enough power to run multiple Promox VM’s to do tests without impacting my other compute nodes.

The Storage

A decade ago, I bought a Synology NAS (a DS215J) that is still running strong today. It was the cheapest option capable of running Plex decently back then. I added two 3TB drives (which are still working) that filled up surprisingly fast. I used to run apps on it via the Synology Store but it now serves primarily as a backup target for my main NAS.

My main NAS is a Synology DS920+ with around 32TB of usable storage (using SHR with mixed drive sizes). I started with one drive and slowly added more as I found good deals, shucking WD external drives. For a while, with upgraded RAM (20GB), this was my primary compute node for multimedia and document services. Eventually, though, I moved almost everything compute-related off it, letting it focus on its main role: storage. It’s a NAS, after all.

The Networking and the Rest

I’ve invested in TP-Link Omada for my core networking. I considered Ubiquiti but found the prices too high here in Canada for the features I needed. My main switch is a 24-port Omada model (TL-SG3428X) which cost me around 360 CAD; an equivalent Ubiquiti would have been much more expensive. It works great, providing the VLAN support, a few 10 Gbps SFP+ ports, and ample 1 Gbps ports I required.

I also have two TP-Link Omada EAP models for Wi-Fi. They work well, and I appreciate having multiple SSIDs integrated easily within the Omada suite. However, their range isn’t quite as impressive as I’d hoped, but at least they weren’t overly expensive.

One of the most crucial parts arrived last and only recently: a UPS with a PDU. I chose a TrippLite rackmount UPS, the SMART1500LCD because Eaton isn’t readily available here, and similarly spec’d APC rackmount units weren’t reasonably priced or in stock when I looked. I considered refurbished but decided against managing batteries and potential issues with used power equipment.

To keep things tidy, I also 3D-printed a patch panel. Everything fits neatly inside a 15U enclosed rack.

The Software

I’ve tried to simplify my software stack where possible. On the compute nodes (Dells, Beelinks), I’m running Proxmox; three nodes are clustered, while my old Vaio laptop runs standalone Proxmox. My router runs Opnsense bare metal. The Raspberry Pi runs Ubuntu Server, and both NAS systems run Synology’s DSM.

My Proxmox nodes host only virtual machines, I am not using any LXC containers, preferring the full kernel isolation of VMs for my workload and simplicity. Opnsense hosts nothing beyond its core routing and firewall duties.

All my primary virtual machines run Ubuntu Server 24.04 LTS. One VM is dedicated to Home Assistant OS (using their provided image). Another VM is dedicated solely to Wazuh for security monitoring. Other VMs serve as Docker hosts: I installed Docker on each and distribute different types of containers across them.

I’m currently reviewing all the services that I am using and removing the out of date ones and adding slowing new containers that seems interesting.

My current container list includes:

  • Traefik (Reverse Proxy)
  • Authentik (Authentication)
  • Portainer & Portainer Agents (Container Management)
  • AdGuard Home (DNS Filtering - running on two hosts for redundancy)
  • Certbot
  • Nextcloud (File Sync & Collaboration)
  • Homepage (Dashboard)
  • Mealie (Recipe Management)
  • IT-Tools (Web-based Dev Utilities)
  • Omada Controller (Network Management)
  • Uptime Kuma (Service Monitoring)
  • Grafana, Prometheus, InfluxDB (Metrics & Monitoring Stack)
  • WhatsUpDocker (Container Update Notifier)
  • ConvertX ( Self-Hosted online file converter )
  • CommaFeed (RSS Reader)
  • StirlingPDF (PDF Manipulation Tools)
  • Automatic Ripping Machine (ARM) (CD/DVD Ripping)
  • Plex (Media Server)
  • Ollama & OpenWebUI ( Local AI Experimentation on my main pc as of now )

I use Ansible to manage as much of this infrastructure as possible. It’s not perfect, but it significantly helps with performing repeatable actions like updating containers and host systems easily.

The Network

I’ve segmented my network using multiple VLANs, which allows fine-grained control over which devices and networks can communicate. My eventual goal is to further limit access on certain networks to only specific required IPs and domains. Currently, the main purpose is preventing networks with less trusted devices (like IoT or guest Wi-Fi) from accessing networks with sensitive data.

Everything is configured directly on the Opnsense router/firewall for centralized control and easier packet analysis. While this setup provides good separation, media-related device discovery (like casting across VLANs) can sometimes be tricky because mDNS proxying isn’t flawless, and overly complex firewall rules can negate some benefits of segmentation.

Recently, I created several new VLANs to isolate specific containers or groups of containers. Some don’t need internet access at all and are completely isolated, only reachable internally via the Traefik reverse proxy. Others require internet access and reside on different dedicated networks. I use macvlan Docker networking where possible for containers that need their own IP address on a specific VLAN. Virtual machines also reside on their own dedicated VLANs, separate from the Proxmox management interfaces.

Beyond VLANs, I’ve also physically separated management traffic where possible. Key systems like the Proxmox hosts and the main NAS use one physical NIC solely for management access (on a dedicated management VLAN), while another dedicated physical NIC handles all VM and container traffic via a trunk connection carrying multiple VLANs.

The Issues

While most of the setup runs smoothly, some challenges remain. Heat, for instance, became more noticeable recently. After a NAS fan failed and needed replacement, I paid more attention to the circulating heat within the rack. Internal rack temperatures are hovering around 30°C, which is higher than ideal. Much of this seems to originate from the Dell Optiplex towers, especially the one with the 10 Gbps NIC, which runs quite hot. Increased load from more containers and higher usage likely contributes too.

Another challenge involves Nextcloud. Performance was terrible when hosted directly on the Synology NAS (due to HDDs). Moving it to a VM on one of the Beelink nodes significantly improved responsiveness. However, I want Nextcloud containers (like Apache) to use macvlan to get their own IP on a specific VLAN. The problem is that the container sometimes grabs a different IP address upon restart or update, requiring me to manually update its IP in my Traefik configuration file. Potential workarounds include running Nextcloud in its own dedicated VM (avoiding macvlan complexity) or possibly assigning it to the host network, but I haven’t yet found a clean way to assign a specific static IP via macvlan reliably within my current Docker setup.

Another challenge is tackling documentation debt. Over time, I’ve made numerous manual tweaks and changes after the initial Ansible setup without rigorously documenting every scenario or updating the automation scripts. It’s crucial now to ensure these configurations are properly captured and ideally managed via code.

Finally, simple time constraints are an ongoing issue. The hours I used to spend tinkering each week just aren’t there anymore. This means modifications need careful planning to avoid major disruptions.

My To-Do List for 2025

Well into 2025, there’s still plenty I want to achieve this year. Although time is limited, I’m committed to continuing the work and learning as the year progresses.

First, I aim to better plan updates and upgrades. While Ansible helps, stopping services gracefully is important. I had one instance where a database broke during an update because containers weren’t stopped correctly, so I need a reliable process to pause relevant containers before VM or Proxmox host updates.

Another priority is establishing an additional offsite backup location for irreplaceable data. Currently, critical data has at least two copies in different physical locations (on-site primary NAS, on-site backup NAS), which I test periodically. However, a third, offsite copy is necessary for true peace of mind. I’m considering cloud options like Backblaze B2 or potentially setting up another small NAS at a family member’s house.

Reducing heat and power consumption remains essential. This might eventually mean replacing the remaining Dell machine with something smaller, quieter, and more power-efficient like the Beelinks, or other fanless options.

Improving monitoring notifications and automation is also key. I use Uptime Kuma with Telegram notifications, it’s not always as effective or informative as I’d like. While email alerts function, the experience isn’t very user-friendly, so I’m exploring solutions with a better overall UX, possibly integrating more deeply with Grafana alerting or Home Assistant.

Finally, I intend to continue experimenting with local and managed AI solutions. This involves identifying practical, everyday use cases, particularly exploring Retrieval-Augmented Generation (RAG) techniques using local models to interact with my internal documentation and notes. My day job provides access to powerful enterprise AI resources, but applying these concepts effectively at home with personal data presents its own interesting set of challenges.

CC BY-NC-ND
Built with Hugo
Theme Stack designed by Jimmy