How I designed and operate the routing, streaming, and observability layer behind Amor Eterno's entire operations platform — without adopting a public cloud.
The Problem
By 2025, Amor Eterno's operations had grown into a family of separate applications — an Angular control center, a Svelte monitor room, a public event-signage site, and two Android apps — all needing to reach one shared backend securely, over TLS, without each app reinventing routing, certificates, or deployment. Live camera and event streaming added another requirement entirely: low-latency HLS/WebRTC playback that a simple reverse proxy alone couldn't provide.
The Architecture
Caddy sits at the edge, terminating TLS and routing every public domain (suite.amoreternohn.com, live.amoreternohn.com, and others) to the right backend service. Behind it, k3s manifests and overlays run the production and development API deployments, while a Docker Compose stack runs MediaMTX for camera/NVR ingestion and HLS/WebRTC playback, alongside PostgreSQL and Redis for the services that need them.
Observability & Operations
A Prometheus, Grafana, and cAdvisor stack monitors container health and resource usage across the platform, backed by scripted k3s state backups and RTSP channel health checks. Deployments are automated end-to-end: GitHub Actions workflows push development and production builds straight to k3s, with separate pipelines for API code and EF Core database migrations, so a release never depends on a manual step on a server I have to remember.
Why It Matters
Every application in the AE Suite family — internal and public — depends on this edge being right. Designing and operating it solo meant every routing change, certificate renewal, and deployment pipeline had one owner end-to-end, from the Caddyfile to the k3s overlay to the Grafana dashboard that tells me if it's actually working.