Project date: 2026-08-24 Role: Architecture, implementation, validation and operation
A website-like internal operations portal that unifies live telemetry from eleven validated APIs without replacing authoritative tools.
Environment and operating context#
Grafana and specialist platforms provided valuable views, but understanding the whole homelab still required moving between Kubernetes, Proxmox, Longhorn, UniFi, Wazuh, Flux and several dashboards. The goal was a customisable interface that looked and behaved like a coherent website, offered straightforward access to every domain and could evolve into the front end for future AI-assisted operations.
Objective#
LIP was designed as a read-only intelligence and navigation layer. It needed to summarise current state, preserve source ownership, distinguish missing data from healthy zero values, keep credentials on the server side and run on the ARM64 cluster through the same GitOps process as other applications.
Operational value and risk reduction#
Before: Establishing overall health required visiting multiple specialist interfaces and interpreting each data model separately.
After: One website-like portal presents current evidence from eleven validated APIs and links back to authoritative systems.
Risk reduced: Partial connector failures are exposed explicitly, credentials remain server-side, and the convenience layer has no infrastructure-changing permissions.
Architectural decisions and alternatives#
- Grafana only
- Excellent for metric dashboards, but less suited to mixed inventory, navigation, documented states and custom cross-system workflows.
- Direct links page
- Simple, but provides no current evidence or normalised exception handling.
- Buy a commercial operations platform
- Potentially broader, but unnecessary cost and less control over a deeply customised homelab model.
- Selected design
- A Next.js portal with server-side read-only connectors provided the required website experience and extension path for AI.
Technical challenges#
The hardest integration was SOC. Wazuh Manager and Indexer use different authentication models, and the internal certificates did not match the Kubernetes service DNS names. Certificate material also had to be exported and imported safely across volume contexts. Multi-source dashboards introduced another challenge: one unavailable connector could not be allowed to crash an otherwise useful page.
Proposed solution#
A Next.js application provides static page shells and server-side API routes. Each route makes fixed, bounded queries to its source, normalises the response and exposes only the data required by the browser. The portal calls Prometheus, Proxmox telemetry, UniFi Network and Protect, Wazuh, storage and Flux evidence without accepting arbitrary infrastructure queries.
Browser -> Next.js UI -> server-side read-only APIs
|-- Prometheus / Kubernetes / Flux
|-- Proxmox / storage
|-- UniFi Network / Protect
`-- Wazuh Manager / IndexerImplementation#
The portal includes Overview, Administration, Infrastructure, Inventory, Kubernetes, Monitoring, Network, Proxmox, Services, SOC, Storage and CCTV pages. Knowledge content was deliberately removed so Git repositories remain the documentation authority.
GitHub Actions builds AMD64 and ARM64 images and publishes them to GHCR. Flux image automation selects the main image digest and updates the GitOps repository. Kubernetes then reconciles the Deployment and its encrypted connector credentials.
Security and operational controls#
- Server-side connector credentials only
- SOPS-encrypted Kubernetes Secrets
- Dedicated Wazuh Manager and Indexer readers
- NetworkPolicy restricted to ports 55000 and 9200
- No arbitrary PromQL from users
- No restart, reconciliation, response or backup actions
- Source-system authentication remains authoritative
- Partial connector failures render as unavailable rather than zero
Validation and measurable outcomes#
| Production APIs tested | 11 |
| Successful HTTP responses | 11 |
| Failed responses | 0 |
| Portal pod readiness | 1 of 1 |
| Pod restarts | 0 |
| Flux Kustomization | Ready |
| Container reference | Immutable SHA-256 digest |
| Image architectures | AMD64 and ARM64 |
Acceptance validation also checked the production build, TypeScript, Kubernetes rollout, mounted credentials and CA bundle, application logs and browser rendering. The Wazuh certificate issue was resolved with pinned trust and narrowly scoped certificate handling rather than globally disabling TLS verification.
Outcome#
LIP now provides one coherent operational surface across the homelab while preserving the depth and authority of the specialist platforms. It shortens the path from “something may be wrong” to the relevant evidence and management tool.
Skills demonstrated#
- Next.js and TypeScript
- API integration and normalisation
- Prometheus and Kubernetes telemetry
- GitHub Actions and multi-architecture containers
- Flux deployment
- TLS and certificate troubleshooting
- Least privilege and NetworkPolicy
- Operational user-experience design
Lessons learned#
A trustworthy portal is defined by failure behaviour as much as successful data. An unavailable connector must never become a reassuring zero, and a ready Deployment must not be described as an end-to-end application check.
Current status and next steps#
Operational. The next planned capability is a standalone advisory chatbot, followed later by tightly bounded read-only portal tools and approved documentation retrieval.
Explore the implementation#
View the portal source on GitHub or read the SOC integration case study.
How it was done#
- Defined the portal boundary. LIP was designed as a read-only operational interface, not a replacement control plane. Proxmox, Kubernetes, Grafana, Wazuh, UniFi and other source systems retained authentication and administrative ownership.
- Created the Next.js application shell. A consistent layout, Sidebar, responsive page structure, status cards, shared tables and navigation were built before live integrations were added.
- Implemented the first telemetry routes. Server-side API routes queried Prometheus and exposed bounded summaries for Kubernetes, infrastructure and monitoring without accepting arbitrary PromQL from the browser.
- Added platform-specific connectors. Proxmox, storage, UniFi Network, UniFi Protect and Flux data were introduced through dedicated normalisation routes and dashboard components.
- Built the SOC integration. Separate least-privilege Wazuh Manager and Indexer identities were created. Certificate material was transferred across storage boundaries, pinned in a mounted trust bundle and restricted by NetworkPolicy.
- Hardened partial-failure behaviour. Home and Inventory were changed so a 503 response from one optional connector produced an unavailable card rather than a JavaScript exception or a false healthy value.
- Containerised the application. GitHub Actions validates the Next.js build and publishes AMD64 and ARM64 images to GHCR, allowing development on Windows and deployment to ARM64 k3s.
- Connected the release to Flux. Image automation detects the new portal image, records an immutable digest in GitOps and reconciles the Kubernetes Deployment.
- Standardised the source. Compressed generated code was reformatted for maintenance, while graphical Sidebar icons were represented with JavaScript Unicode escapes to avoid Windows encoding corruption.
- Completed production acceptance. The pod, mounted credentials, CA bundle, logs, browser pages and all eleven API endpoints were checked. Every production endpoint returned HTTP 200.
Evidence methodology#
The figures in this case study were derived from reproducible source and runtime checks rather than estimates.
- Every production API route was requested over the deployed ingress and its HTTP status recorded. Eleven of eleven returned HTTP 200.
- Kubernetes readiness and restart counts were collected for the live portal pod, followed by a recent-error log scan.
- Build, route, image-digest, Flux reconciliation and browser checks were part of release acceptance.
Limitations and residual risks#
- LIP reports and correlates evidence but is not an authoritative management interface.
- Some Services entries indicate workload readiness rather than a full transaction-level health test.
- NetBox is excluded from trusted totals until its records are reconciled.
- The Wazuh connector currently uses narrowly scoped certificate hostname handling pending certificate reissue.
Plain-English glossary#
- Normalised API
- A portal endpoint that converts source-specific data into a consistent response for the user interface.
- Read-only connector
- An integration identity and route that can retrieve evidence but cannot change the source system.
- Partial failure
- A condition where one data source is unavailable while the remainder of the page stays usable.
Independent validation#
This was a self-directed engineering project rather than a client engagement. Credibility is established through deployed configuration, source history, successful builds, operational measurements, restoration tests and repeatable validation rather than a client testimonial.