Live telemetry integration coming soon — chart containers are ready for data binding.
⚡
CPU Usage
Pending
CPU LOAD — AWAITING DATA
Nodes
pve01, pve02, pve03
Interval
30 s
🧠
Memory Usage
Pending
RAM UTILIZATION — AWAITING DATA
Nodes
pve01, pve02, pve03
Interval
30 s
💾
Storage
Pending
DISK CAPACITY — AWAITING DATA
Pools
local-lvm, ceph, nfs
Interval
5 min
🌐
Network I/O
Pending
NETWORK THROUGHPUT — AWAITING DATA
Interfaces
vmbr0, vmbr1
Interval
10 s
Andromeda — Home Lab Mission Control
A self-hosted infrastructure dashboard providing real-time telemetry, service monitoring, and secure access to homelab services.
Architecture
🌐Browser
▶
⚡Pages Function Proxy
▶
☁️Cloudflare Edge
▶
🔒Cloudflare Tunnel
▶
📦cloudflared LXC
▶
🖥️Proxmox VE API
Every API request from the browser is intercepted by a Cloudflare Pages Function running at the edge. The function authenticates the request using a session cookie, injects the Proxmox API token from a secret environment variable, and proxies the call through a Cloudflare Tunnel to a cloudflared LXC container running on the Proxmox node. The Proxmox VE API responds with live cluster data — the browser never sees the credentials.
Tech Stack
🟨
Vanilla JS
No framework — SPA router, DOM rendering, and fetch all hand-rolled.
⚡
Cloudflare Pages Functions
Edge-side API proxy — keeps credentials server-side and out of the browser.
🗄️
Cloudflare D1
SQLite at the edge — stores user accounts with SHA-256 hashed passwords.
🔒
Cloudflare Tunnel
Zero-trust inbound tunnel — no open ports on the home network.
🖥️
Proxmox VE API
RRD telemetry and cluster resource data sourced directly from the hypervisor.
📊
Chart.js
Lightweight canvas charts for CPU, memory, storage, and network I/O.
🌐
Tailscale
WireGuard mesh VPN — direct access to services from any device on the tailnet.
Features
🔑
Auth
Invite-code gated registration and session-cookie login. Passwords are hashed with SHA-256 via the Web Crypto API before storage in Cloudflare D1.
Troubleshooting Story
Login returned 200 but the page never changed. The HttpOnly flag on the session cookie made it invisible to JavaScript, so the router always saw the user as unauthenticated and silently redirected back to the login screen.
📡
Dashboard
Live service health grid showing all Proxmox LXC containers and VMs. Status dots pulse green for online, amber for standby, and grey for offline. Auto-refreshes every 30 seconds.
Troubleshooting Story
The service grid returned "missing API token" even though the environment variable was set. Debug logging revealed a trailing space in the variable name — the code looked up PROXMOX_TOKEN_VALUE but Cloudflare stored PROXMOX_TOKEN_VALUE . Invisible characters, real bug.
🔗
Quick Links
Clickable tiles for every self-hosted service — Nextcloud, Vaultwarden, Jellyfin, AdGuard, Matrix, and more. Each tile shows a live status dot sourced from the Proxmox API. Tailscale URLs are used for direct mesh access.
📈
System Overview
Four live Chart.js charts rendering one hour of RRD telemetry from the Proxmox node: CPU utilisation, memory usage, root disk capacity, and network I/O. Refreshes every 60 seconds.
Troubleshooting Story
Chart.js loaded from a CDN URL pointing to a nonexistent version. The CDN returned an HTML error page, the browser rejected it for MIME type mismatch, and the failed script tag cascaded — breaking every script that loaded after it, including the router and login.
Infrastructure
The homelab runs on a single Proxmox VE node hosting 11 LXC containers — each service isolated in its own container with dedicated resource limits. A dedicated cloudflared container maintains the outbound Cloudflare Tunnel, eliminating the need for any open inbound ports on the home network. Tailscale is installed on the node and key containers, providing a WireGuard-encrypted mesh network for direct device-to-service access from anywhere on the tailnet without routing through the public internet.
Projects & Progress
An active build log, not a finished portfolio. These are the things I'm shipping, debugging, and iterating on right now — documented as they evolve, rough edges and all.
Featured Build
📞
OpenLine
Missed-call recovery SaaS for service businesses.
Live
The Problem
Service businesses — HVAC, plumbers, med spas — lose real revenue every time a call goes unanswered. OpenLine detects the missed call the moment it happens, then an AI drafts and runs an SMS conversation with the caller to qualify the lead and book the job, surfacing every lead in a dashboard.
Tech Stack
Next.jsTursoTwilioVercel
Current Status
Live webhook pipeline confirmed working end-to-end.
Toll-free SMS verification pending with Twilio.
Dashboard restyled to match the OpenLine brand.
Technical Highlight
A real test call to the toll-free number went unanswered and never created a lead — the primary voice webhook simply wasn't firing. Hours of debugging pointed at the code, the Twilio number config, regions… all fine. The actual root cause: the Twilio account was still in trial mode, which gates inbound calls behind a "press any key" trial-mode IVR message before the voice webhook is ever fetched. The call was hanging up at that gate, so the handler never ran — nothing in the code was broken, the account just needed upgrading. Confirmed the full pipeline works by replaying a signed synthetic webhook end-to-end.