add local service proxy with .numa domains

HTTP reverse proxy on port 80 lets developers use clean domain names
(frontend.numa, api.numa) instead of localhost:PORT. Includes WebSocket
upgrade support for HMR, TCP health checks, dashboard UI panel, and
REST API for service management. numa.numa is preconfigured for the
dashboard itself.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Razvan Dimescu
2026-03-20 15:07:15 +02:00
parent 14a9e9e7e3
commit 8f959ce0a5
15 changed files with 762 additions and 53 deletions

52
src/service_store.rs Normal file
View File

@@ -0,0 +1,52 @@
use std::collections::HashMap;
use serde::Serialize;
#[derive(Clone, Serialize)]
pub struct ServiceEntry {
pub name: String,
pub target_port: u16,
}
pub struct ServiceStore {
entries: HashMap<String, ServiceEntry>,
}
impl Default for ServiceStore {
fn default() -> Self {
Self::new()
}
}
impl ServiceStore {
pub fn new() -> Self {
ServiceStore {
entries: HashMap::new(),
}
}
pub fn insert(&mut self, name: &str, target_port: u16) {
let key = name.to_lowercase();
self.entries.insert(
key.clone(),
ServiceEntry {
name: key,
target_port,
},
);
}
pub fn lookup(&self, name: &str) -> Option<&ServiceEntry> {
self.entries.get(&name.to_lowercase())
}
pub fn remove(&mut self, name: &str) -> bool {
self.entries.remove(&name.to_lowercase()).is_some()
}
pub fn list(&self) -> Vec<&ServiceEntry> {
let mut entries: Vec<_> = self.entries.values().collect();
entries.sort_by(|a, b| a.name.cmp(&b.name));
entries
}
}