
Hardware
Compute
| Device | CPU | RAM | Storage | Purpose |
|---|---|---|---|---|
| Beelink GTi 13 | i9-13900H (14C/20T) | 64GB DDR5 | 2× 2TB NVMe | Proxmox (px-0) |
| OptiPlex #1 | i5-6500T (4C/4T) | 32GB DDR4 | 128GB NVMe | Proxmox (px-1) |
| OptiPlex #2 | i5-6500T (4C/4T) | 32GB DDR4 | 128GB NVMe | Proxmox (px-2) |
| Dell R720 | 2× E5-2697v2 (24C/48T) | 192GB ECC | 4× 960GB SSD | Power Testing |
| Synology DS223+ | ARM RTD1619B | 2GB | 2× 2TB RAID1 | NAS/Media |
Network Gear
| Device | Model | Specs | Purpose |
|---|---|---|---|
| ONT | Huawei | 1GbE | ISP Gateway |
| Firewall | XCY X44 | 8× 1GbE | pfSense Router |
| WiFi | TP-Link AX3000 | WiFi 6 | Wireless AP |
| Switch | TP-Link | 24-port | Core Switch |
Power Protection
| Device | Model | Protected Equipment | Capacity |
|---|---|---|---|
| UPS #1 | CyberPower | Mini PCs (Proxmox cluster) | 1500VA |
| UPS #2 | CyberPower | Network gear | 1000VA |
Cloud
| Provider | Instance | Specs | Location | Purpose |
|---|---|---|---|---|
| Oracle | Ampere A1 | 4vCPU/24GB/200GB (~98GB free) | USA | Docker Services + OpenClaw Agent |
Network
Three dedicated physical interfaces on pfSense:
WAN Interface → Orange ISP (Bridge Mode)LAN Interface → Homelab NetworkWiFi Interface → Guest/IoT IsolationWarning
WiFi clients are firewalled from homelab services, except whitelisted ones like Jellyfin.
Tailscale creates a flat network across all locations — homelab and Oracle both appear on the same mesh.

pfSense
A fanless mini PC from AliExpress (~200€) running pfSense for 3+ years: 👉 XCY X44 on AliExpress

Tailscale Subnet Router exposes the entire homelab to cloud VPS without installing Tailscale on every device. Also the solution to CGNAT — when your ISP doesn’t give you a public IP, this gets you in. Setup guide →
Unbound DNS runs as a local recursive resolver with domain overrides for *.k8s.merox.dev pointing to K8s-Gateway.
Telegraf pushes system metrics to Grafana.
Firewall rules: WiFi → LAN blocks everything except whitelisted apps; LAN → WAN allows all; WAN → Internal blocks all except explicitly exposed services.
Tip
The Oracle instance doubles as a Tailscale exit node, useful for routing traffic through the US when needed.
Virtualization
Proxmox Cluster
Three-node cluster across the mini PCs. Each node runs one Talos VM, so Kubernetes has HA across physical hosts with no single point of failure.

Nodes:
| Node | Device | CPU | RAM | Role |
|---|---|---|---|---|
| px-0 | Beelink GTi 13 | i9-13900H (20T) | 64GB | Primary — hosts K8s controlplane-1 |
| px-1 | OptiPlex #1 | i5-6500T (4T) | 32GB | K8s controlplane-2 |
| px-2 | OptiPlex #2 | i5-6500T (4T) | 32GB | K8s controlplane-3 |
Storage:
| Pool | Type | Used | Total |
|---|---|---|---|
| cluster-storage | ZFS | 713GB | 899GB |
| synology-nas | NFS | 985GB | 1.4TB |
| local-data | dir | 177GB | 812GB |
Current VMs:
| VM | Purpose | Specs | Status |
|---|---|---|---|
| kubernetes-controlplane-1 | K8s node (px-0) | 8vCPU/24GB | Running |
| kubernetes-controlplane-2 | K8s node (px-1) | 4vCPU/16GB | Running |
| kubernetes-controlplane-3 | K8s node (px-2) | 4vCPU/16GB | Running |
| Windows 10 | Lab / testing | 4vCPU/12GB | Stopped |
| Windows Server 2019 | AD Lab | 8vCPU/14GB | Stopped |
| Windows 11 | Remote desktop | 8vCPU/16GB | Stopped |
Note
Home Assistant, Kali Linux, and GNS3 are backed up to Synology NAS — restored on demand when needed, not kept running permanently.
Intel Iris Xe GPU on px-0 is passed through to the kubernetes-controlplane-1 VM for Jellyfin hardware transcoding (Intel QuickSync).
Synology DS223+
Dual purpose: NFS/SMB shares for the ARR stack (still experimenting with both protocols), and personal cloud via Synology Drive.
After 3 years of self-hosting Nextcloud, I switched. Better performance, native mobile apps that actually work, and zero maintenance. Sometimes the best self-hosted solution is the one you never have to think about.

Dell R720
The power-hungry workhorse. Its role has changed a few times:
| Period | Purpose | Configuration |
|---|---|---|
| Phase 1 | Proxmox hypervisor | 24C/48T, 192GB RAM |
| Phase 2 | AI Playground | Quadro P2200 + Ollama + Open WebUI |
| Phase 3 | Backup Target | 4× 960GB RAID-Z2, Garage S3 backend |
| Current | Power Testing | Occasional boots to measure idle/load consumption |
The most interesting project was flashing the PERC controller to IT mode — bypasses hardware RAID so the OS sees drives directly. Fohdeesha’s crossflash guide covers H710/H310 and more.

At ~200W idle, running 24/7 costs ~€20/month in electricity. Right now it’s off most of the time — I boot it occasionally to benchmark power usage and figure out if there’s any workload that justifies keeping it on. Still undecided.
Power Management
The CyberPower UPS covers all mini PCs and network gear. When power fails, it triggers a cascading shutdown — Kubernetes nodes drain properly before Proxmox hosts go down.
| Feature | Implementation | Purpose |
|---|---|---|
| pwrstat | USB to GTi13 Pro | Automated shutdown orchestration |
| SSH Scripts | Custom automation | Graceful cluster shutdown |
| Monitoring | Telegram alerts | Real-time power notifications |


Kubernetes
Fair warning: this is where I went full “because I can” mode. If you just want to run services, Docker is the right answer. But if you want to learn enterprise-grade container orchestration in your homelab, keep reading.
The starting point: onedr0p/cluster-template
Talos OS was the first immutable, declarative OS I’d run. After a few days of troubleshooting, I was sold.
Tip
Why Talos over K3s? Immutable OS means less maintenance, GitOps-first design, declarative everything, and it’s closer to what you’d run in production.
My infrastructure repo: 👉 github.com/meroxdotdev/infrastructure
Key customizations:
| Component | Modification | Reason |
|---|---|---|
| Storage | Longhorn CSI | Simpler PV/PVC management |
| Talos Patches | Custom machine config | Longhorn requirements |
| Custom Image | factory.talos.dev | Intel iGPU + iSCSI support |
GitOps structure:
kubernetes/apps/├── cert-manager/ # TLS automation├── default/ # Production workloads├── flux-system/ # Flux operator + instance├── kube-system/ # Cilium, CoreDNS, NFS CSI, metrics-server├── network/ # k8s-gateway, Cloudflare tunnel + DNS├── observability/ # Prometheus, Grafana, Loki└── storage/ # Longhorn configuration

Deployed apps:
| App | Purpose | Notes |
|---|---|---|
| Radarr | Movie automation | NFS to Synology |
| Sonarr | TV automation | NFS to Synology |
| Prowlarr | Indexer manager | Central search |
| qBittorrent | Torrent client | Gluetun sidecar + SurfShark WireGuard VPN |
| Jellyseerr | Request management | Public via Cloudflare |
| Jellyfin | Media server | Intel QuickSync enabled |
| n8n | Workflow automation | |
| Homepage | Dashboard | |
| Grafana | Metrics dashboards | |
| Prometheus + Alertmanager | Metrics collection + alerts | |
| Loki + Promtail | Log aggregation | |
| Netdata | Per-node system monitoring | DaemonSet — one agent per K8s node |
| cert-manager | TLS certificate automation | ACME via Let’s Encrypt |
The live dashboard is public — current service status at inside.merox.dev.
LoadBalancer IPs are handled by Cilium’s L2 announcement — a pool of addresses (10.57.57.100–120) announced directly on the LAN via ARP, no external load balancer needed. Services like qBittorrent, k8s-gateway, and the Cloudflare tunnel endpoint each get a dedicated IP from this pool.
With this setup I can fully rebuild the cluster in 8–9 minutes — declarative config for everything, GitOps workflow with Flux, Renovate bot keeping dependencies updated.
Warning
Keep your SOPS keys backed up separately. You’ll need them to decrypt the repository when rebuilding from scratch.
For cluster deployment details, the onedr0p/cluster-template README is surprisingly well written and worth following directly.
Services
Managed through a single Portainer instance at cloud.merox.dev:

cloud-usa (Oracle Free Tier Ampere A1) — the only cloud node. Always-on, handles external access, backup target via rsync, and runs the OpenClaw infrastructure agent:
| Service | Purpose |
|---|---|
| Traefik | SSL for all VPS services |
| Pi-hole | Dedicated Tailscale split-DNS |
| Portainer | Container management |
| Homepage | Dashboard |
| Guacamole | Remote access via Cloudflare Tunnel |
| Uptime Kuma | Service uptime monitoring |
| Glances | System resource monitoring |
| Joplin Server | Self-hosted notes sync |
| OpenClaw | AI infrastructure agent (Telegram → kubectl/flux/docker) |
| Garage S3 + WebUI | S3-compatible object storage for Longhorn backups |
| Rsync endpoint | Off-site backup target from Synology NAS |
homelab-ro (local Docker) — lightweight services on the local Docker host:
| Service | Purpose |
|---|---|
| Netboot.xyz | PXE / network boot |
| Portainer Agent | Remote Docker management |
Note
Netdata runs as a Kubernetes DaemonSet — one child agent per node, one parent for aggregation — not as a standalone Docker container.
Tip
Full OpenClaw setup: Running OpenClaw as a Homelab Infrastructure Agent.
Backup
- Longhorn PVCs → Garage S3 on Oracle Cloud (S3-compatible backup)
- Synology NAS → rsync to Oracle Cloud instance (off-site copy)
Kubernetes PVCs │ ▼Garage S3 (Oracle Cloud VPS, 200GB disk) ◄── Synology NAS rsync
Garage runs on the Oracle VPS’s single 200GB boot disk — currently ~28GB used by Garage data, ~98GB free total. Not a lot of headroom, but more than enough for compressed PVC snapshots at this scale.
MinIO was the original S3 backend until it discontinued its Docker images and moved to a source-only model with known CVEs on older builds. Garage replaced it — lightweight, S3-compatible, runs fine on the Oracle free tier. Full migration walkthrough: Migrating Longhorn Backup from MinIO to Garage.
The R720’s backup role has been retired entirely — Garage on Oracle handles Longhorn backups, Synology handles local redundancy (2× 2TB RAID1) and rsyncs off-site to the same VPS. Simpler than spinning up a 200W server for weekly sync jobs. For full details on the backup chain and recovery procedures, see Safeguarding My Critical Data.