Architecture¶
This document describes the internal design of prox for contributors.
Design Principles¶
-
Subscriber-based log output — Terminal output is a subscriber to the log buffer, not a special case. This enables TUI, API streaming, and future daemon mode without architectural changes.
-
API always available — Even in foreground mode, the HTTP API runs and accepts connections.
-
Filter/search in core — Filtering primitives live in the log manager and are exposed to all consumers (TUI, API, CLI).
Internal Structure¶
┌─────────────────────────────────────────────────────────┐
│ Supervisor │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Process 1 │ │ Process 2 │ │ Process N │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ └────────────────┼────────────────┘ │
│ ▼ │
│ ┌─────────────┐ │
│ │ Log Manager │ │
│ │ (ring bufs) │ │
│ └──────┬──────┘ │
│ │ │
│ ┌────────────────┼────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌──────────┐ ┌───────────┐ ┌───────────┐ │
│ │ Terminal │ │ HTTP API │ │ TUI │ │
│ │Subscriber│ │ + SSE │ │(bubbletea)│ │
│ └──────────┘ └───────────┘ └───────────┘ │
└─────────────────────────────────────────────────────────┘
Log Manager¶
- Ring buffer per process (configurable size, default 1000 lines or 1MB)
- Each entry:
{timestamp, process, stream (stdout|stderr), line} - Supports multiple concurrent readers/subscribers
- Filter primitives: by process, by pattern (substring or regex)
- Subscribers receive log entries via channels
Process Manager¶
- Spawns and manages child processes
- Captures stdout/stderr, routes to log manager
- Handles graceful shutdown (SIGTERM → wait → SIGKILL)
- Tracks process state, PID, uptime, restart count
- Runs health checks if configured
Process Lifecycle¶
Startup¶
- Parse config file
- Load environment (global .env, per-process env_file, per-process env)
- Start HTTP API server
- Start each process
- Begin health checks (if configured)
- Attach log subscribers (terminal or TUI)
Shutdown (Ctrl+C or API)¶
- Stop accepting new API requests
- Send SIGTERM to all child processes
- Wait for graceful shutdown (default 10 seconds)
- Send SIGKILL to any remaining processes
- Exit
Process Restart¶
- Send SIGTERM to process
- Wait for shutdown (timeout → SIGKILL)
- Reset restart counter if appropriate
- Start process again
- Reset health check state
Health Checks¶
- Start after
start_periodelapses - Run at
interval - Mark unhealthy after
retriesconsecutive failures - Mark healthy after one success
- Health state exposed via API and TUI
HTTPS Reverse Proxy¶
The optional HTTPS reverse proxy provides subdomain-based routing to local services.
Proxy Architecture¶
┌──────────────────────────────────────────────────────────────────┐
│ HTTPS Reverse Proxy │
│ │
│ Browser Request │
│ https://app.local.dev:6789/api/users │
│ │ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ Subdomain Router │ Extract "app" from host │
│ │ (extract + lookup) │ │
│ └──────────┬──────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ Route Table │────▶│ Request Manager │ │
│ │ app → :3000 │ │ (ring buffer) │ │
│ │ api → :8000 │ └─────────────────────┘ │
│ └──────────┬──────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ httputil.ReverseProxy│ │
│ │ → localhost:3000 │ │
│ └─────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
Package Structure¶
internal/proxy/
├── proxy.go # Main proxy service, router, request handling
├── requests.go # Request manager (ring buffer, subscriptions)
├── certs/
│ └── certs.go # mkcert integration for certificate management
└── hosts/
└── hosts.go # /etc/hosts management
Request Flow¶
- Incoming HTTPS request to
*.domain:port - Extract subdomain from Host header
- Look up service in route table
- Forward request via
httputil.ReverseProxy - Record request in RequestManager
- Return response to client
Technologies¶
| Component | Technology | Notes |
|---|---|---|
| Language | Go 1.23+ | Concurrency, single binary |
| TUI | bubbletea | Elm-architecture TUI framework |
| TUI styling | lipgloss | Styling for bubbletea |
| HTTP router | chi or stdlib | Lightweight, idiomatic |
| Reverse Proxy | net/http/httputil | Standard library reverse proxy |
| YAML parsing | gopkg.in/yaml.v3 | Standard YAML library |
| Env file | godotenv | .env file loading |
| Certificates | mkcert | Local CA for development certs |