They say the true mark of a homelabber is when you start documenting the uptime of services that nobody uses but you. Well, consider me officially inducted.

Today, I’m publishing the State of My Homelab, but this isn’t just a server sitting in a closet. This is a geographically distributed hybrid-cloud setup with redundant connectivity and monitoring. I live in Mumbai, but my actual bare-metal Edge Homelab sits at the very southern tip of India in Kanyakumari.

To bridge the gap between my Mumbai apartment, my Kanyakumari homelab, and my Oracle Cloud instance, everything is securely meshed together via Tailscale.

               [ Tailscale Secure Mesh ]
                 │         │         │
      ┌──────────┘         │         └──────────┐
      ▼                    ▼                    ▼
Mumbai (Apt)         Oracle Cloud       Kanyakumari (Edge)
(Management)         (Public Node)              │
                           │                    ├─ OpenWrt Router
                           │                    │   ├─ Primary: Fiber
                           │                    │   └─ Backup: BSNL 4G
                           │                    │
[Public Internet] ─────────┘                    └─ Proxmox Hypervisor
(Mobile Phone Ingress)                               ├─ Immich
                                                     ├─ LibreSpeed
                                                     ├─ Monitoring
                                                     └─ Windows VM

The Edge Node: Hacked Asus Chromebox 3

Down in Kanyakumari, my core hypervisor is running on an ASUS Chromebox 3 (codenamed “Teemo”), flashed with custom coreboot-based firmware from MrChromebox. This gives me solid x86 performance in an ultra-low-power, silent, NUC-style form factor.

  • CPU: Intel Core i7-8550U (4 Cores, 8 Threads)
  • RAM: 16GB LPDDR4
  • Storage:
    • 250GB Samsung 980 NVMe (OS/VMs): A true workhorse. With over 31,800 hours of 24/7 power-on time (3.6 years!) and 30.6 TB written, it still has 78% of its lifespan remaining and zero integrity errors.
    • 5TB Western Digital HDD: A massive external drive sitting at a perfectly cool 40°C, used for Proxmox backups and my Immich photo library.

This Proxmox Virtual Environment (PVE) runs a mix of lightweight Linux Containers (LXCs) and one full Virtual Machine:

  • VM 100 (windows): A full Windows VM, because sometimes you just inevitably need a Windows environment.
  • LXC 101 (deye-exporter): Yes, I monitor my solar inverter. Because what’s a homelab without scraping metrics from your roof?
  • LXC 102 (docker): A dedicated container specifically for running isolated Docker workloads.
  • LXC 103 & 104 (monitoring & prometheus): The nerve center for observability.

With the base hypervisor running, the next step was getting the actual services up.

Self-Hosted Edge Applications

Inside my Proxmox Docker LXC, I host a few critical applications:

  • Immich: The absolute ultimate self-hosted Google Photos alternative. My entire life’s photo library is backed up here, utilizing PostgreSQL, Redis, and a dedicated Machine Learning container.
  • go2rtc: Just for “timepass,” it pulls an RTSP stream from my home’s iDS-7208HUHI-M1 DVR.
  • Librespeed: A local speedtest server. I use this to diagnose why my upload bandwidth from Mumbai back to Kanyakumari sometimes drops when I’m syncing photos to Immich!
  • Mysterium Node: Passive bandwidth sharing. (Because if your homelab isn’t generating pennies, is it even a homelab?)

The 3-2-1 Backup Strategy: Restic & Offsite Storage

Because my entire life’s photo library sits on that 5TB HDD, a robust backup strategy is non-negotiable. I rely on a simple but bulletproof Restic bash script that runs daily on the Proxmox host.

It completely encrypts, chunks, and deduplicates the /mnt/hdd/immich-app directory, the PostgreSQL databases, and my core /etc/pve configs. It then pushes everything simultaneously to Google Drive (via rclone) and Backblaze B2.

# Backblaze B2 Backup
restic -r b2:adine-restic-backup:/ \
--password-file /root/restic-password.txt \
backup /mnt/hdd/immich-app /mnt/hdd/pgdata /etc/pve /root \
--exclude-file=/root/restic-exclude.txt \
--limit-upload 30000000

# Automated Pruning
restic -r b2:adine-restic-backup:/ \
--password-file /root/restic-password.txt \
forget --keep-daily 7 --keep-weekly 4 --keep-monthly 3 --prune

By explicitly capping the upload limit at 30 Mbps (--limit-upload 30000000), I ensure these massive offsite backups never completely saturate my primary WAN link while they run in the background.

While the Edge Node handles the heavy lifting locally, I also wanted an isolated cloud environment to keep an eye on things from the outside.

The Cloud Node: Oracle Free Tier

I managed to snag one of Oracle Cloud’s legendary “Always Free” Ampere A1 instances (4 OCPU, 24 GB RAM, ARM64, ~200 GB storage, currently running 24/7 for basically ₹0). It runs an entirely isolated Prometheus/Grafana stack, Portainer, and Matterbridge.

The Public Ingress Tunnel: Because my Kanyakumari edge node sits behind a strict double-NAT without any port forwarding, I use this Oracle instance as a public ingress point. It runs a lightweight tunnel that securely routes public internet traffic over the Tailscale mesh directly to my internal Proxmox environment.

This is extremely useful for Immich. By port forwarding the tunnel endpoint on the Oracle cloud, I can continuously backup photos from my phone on the go by simply connecting to oracle-ip:port. This completely removes the need to leave the Tailscale app running 24/7 on my phone, saving precious battery life!

Fun fact about Matterbridge: I actually worked as a Technical Support Specialist and Community Lead for Mysterium Network for 5 years! I set up Matterbridge to bridge our Mysterium Telegram and Discord communities together, and I just never took it down.

Of course, none of this matters if the Edge Node loses internet access. So let’s talk about the network architecture.

The Network: Enterprise PoE+ & Dual-WAN LTE

My goal is for the moment the primary Fiber line drops in Kanyakumari, I want all traffic kicked over to my backup cellular connection, and I want Uptime Kuma to know about it instantly.

The LAN Backbone: 24-Port PoE+ + 10G Uplinks: Before we talk about the WAN, we have to talk about the internal LAN. During the construction of my house, I made the best design choice possible: every single room and TV is hardwired with Ethernet.

All of those wall jacks route back to an absolute monster of a switch: a TP-Link TL-SG3428XMP JetStream. It’s an L2+ managed switch featuring twenty-four Gigabit PoE+ ports (with a massive 384W power budget) and four 10G SFP+ uplinks. It plugs directly into the LAN side of my OpenWrt router, and allows me to casually plug Raspberry Pis into random wall jacks around the house whenever I feel like it!

The Backup WAN Secret: My OpenWrt router is actually a TP-Link Archer C6. My primary WAN is a Fiber ONU (192.168.1.1). My secondary WWAN isn’t just a standard connection. It’s a TP-Link Archer MR100 4G router (192.168.2.1) configured to use LTE Band 28. Why? Because BSNL gives a solid 20-35 Mbps down and 15-25 Mbps up on Band 28, all for a 411 Rs/60-day plan (100GB limit).

The cursed part? My OpenWrt Archer C6 connects to the MR100 wirelessly as a Wi-Fi station (phy0-sta0) because I couldn’t be bothered to run an Ethernet cable between them.

The Double-NAT Sad Reality: Currently, my OpenWrt WAN port actually connects to the fiber ONU as a standard LAN client instead of using PPPoE. Why? Because the ISP locks the MAC address on their end, and MAC cloning didn’t work! So right now, I’m stuck dealing with double-NAT behind their CGNAT. One day I’ll have to call them up to fix it so OpenWrt can handle the PPPoE dialing directly, leaving the ONU to act purely as a dumb fiber bridge.

The Zombie Connection Drain: When failing back from BSNL to Fiber, OpenWrt’s default behavior is to let active TCP connections “drain” naturally. This meant a heavy download would stay locked onto my metered BSNL line even after Fiber was restored, draining my 100GB data cap!

  • The Fix: Configuring OpenWrt’s flush_conntrack setting to ifup. Now, the absolute millisecond Fiber comes back online, OpenWrt ruthlessly severs all BSNL connections, forcing them to reconnect over the unlimited Fiber line.

With dual-WAN failover working reliably, I needed a way to actually visualize those network transitions in real-time.

Monitoring It All: The Custom Go Exporter

I wanted Uptime Kuma to track the status of both WANs independently.

The Solution: We built a custom Go Exporter running in my Proxmox monitoring LXC. It securely SSHs into the OpenWrt router, fetches the raw MWAN3 status via ubus call mwan3 status, caches it in an atomic lock, and exposes a lightning-fast HTTP JSON endpoint.

The monitoring LXC runs a local Uptime Kuma instance that pings this Go Exporter every 5 seconds. Meanwhile, my Oracle Cloud Uptime Kuma uses the Tailscale mesh to ping the main Proxmox IP to monitor overall house power/internet connectivity.

Conclusion

Is checking my WAN connection every 5 seconds overkill? Absolutely.

Does managing an ultra-reliable, dual-WAN, Tailscale-meshed homelab in Kanyakumari from an apartment in Mumbai make me feel like a true infrastructure engineer? 100%.

Next up on the homelab roadmap: well, actually, I already gutted my 600VA APC UPS and stuffed a massive 30Ah LiFePO4 battery inside it just so my pristine Uptime Kuma graphs outlive the power grid. But I think my 7.1kWh solar battery setup deserves its own dedicated “Part 2” blog post…