Architecture
Single host, explicit surfaces.
The core design choice is not to hide complexity behind orchestration layers that the host size does not justify. Containers are used for isolation and deployability, while networking and runtime boundaries stay inspectable.
flowchart TD
User["Client"] --> DNS["Public DNS"]
DNS --> Nginx["Nginx reverse proxy"]
Nginx --> Shellr["shellr.net"]
Nginx --> DMA["dma.shellr.net"]
Nginx --> Grafana["grafana.shellr.net"]
Nginx --> Status["status.shellr.net"]
Shellr --> App["Portfolio app container"]
DMA --> DMAApp["DMA app container"]
DMAApp --> DB["MariaDB"]
Grafana --> Metrics["Prometheus metrics"]
Grafana --> Logs["Loki logs"]
Status --> Kuma["Uptime Kuma"]
Docs["docs.shellr.net"] --> Pages["GitHub Pages"]