Public Edge + Homelab Platform — Caddy edge routing, Kubernetes, Observability, AI Applications
| Hostname | Type | Origin | Description |
|---|---|---|---|
climacs.net |
STATIC | edge VM /srv |
Portfolio site — Astro build output |
www.climacs.net |
REDIRECT | edge VM Caddy |
301 redirect to apex |
vault.climacs.net |
PROXY | vault LXC :8080 |
Vaultwarden — password manager (isolated LXC) |
copilot.climacs.net |
PROXY | edge VM :3000 |
EKS Triage Copilot — AI operations UI |
nero.climacs.net |
PROXY | apps VM :3000 |
NeroCamp — scheduling app (Next.js) |
finops.climacs.net |
PROXY | apps VM :8002 |
AWS Cost Dashboard — FinOps demo |
runbook.climacs.net |
K8S | k8s worker-2 :80 |
Homelab Runbooks — Kubernetes Ingress |
prometheus.climacs.net |
K8S | k8s worker-1 :31041 |
Prometheus — monitoring metrics (HTTPS origin) |
grafana.climacs.net |
K8S | k8s worker-1 :30080 |
Grafana — dashboards (NodePort 30080) |
The single public entry point for all *.climacs.net traffic.
The home router forwards ports 80/443 to this VM. Caddy handles automatic TLS
and routes requests to local containers or LAN services.
The BFF sits between the React frontend and AWS API Gateway. The browser never touches AWS directly — the API key is injected server-side only. Every request passes through a layered guardrail stack before being forwarded.
slowapi · RATE_LIMIT=10/minute/api/<endpoint> POST routes.
Returns HTTP 429 when exceeded.
Limit is configurable via .env without code changes.
guardrails.py · 6 regex patternsAKIA…)
aws_access_key_id / aws_secret_access_key
xoxb-)
ghp_…)
MAX_REQUEST_BYTES=51200 (50 KB)ALLOWED_ENDPOINTS = {triage, explain, runbook-snippet}logger.info(metadata only)conv_id[:8], endpoint,
status_code, latency_ms.
Full prompts and responses are never logged to stdout.
Only persisted (encrypted at rest) in PostgreSQL history.
_cleanup_response() · per-endpoint```json)
"key": "value" dict responses to readable text
{, } lines) from steps lists
\n and \" in runbook markdown
database.py · SQLite (dev) / PostgreSQL (prod)conv_id, endpoint,
model_id, confidence, latency_ms,
status_code. Supports project-based organization,
archiving, soft-delete, and full-text search.
Survives container restarts.
REQUEST_TIMEOUT_SECONDS=30