- Rust 72.5%
- JavaScript 15.7%
- HTML 6.6%
- CSS 4.5%
- Makefile 0.5%
- Other 0.2%
|
Some checks failed
Build & Test / check (push) Has been cancelled
Reviewed-on: #33 |
||
|---|---|---|
| .forgejo/workflows | ||
| crates | ||
| docs | ||
| patches/rustls-acme-0.15.1 | ||
| .env.example | ||
| .gitignore | ||
| buildenv.sh | ||
| Cargo.lock | ||
| Cargo.toml | ||
| Makefile | ||
| README.md | ||
Hero Proxy
HTTP/HTTPS reverse proxy and service discovery for the Hero ecosystem. Routes incoming traffic to Hero services via URL-prefix → Unix domain socket forwarding, with TLS termination (self-signed or Let's Encrypt), SSH tunnels, OAuth, and a full management API.
Architecture
Internet / Browser
│
:80 (HTTP) / :443 (HTTPS)
│
hero_proxy_server
├── {domain}/* → ~/hero/var/sockets/{service}/*.sock
├── TLS (self-signed or Let's Encrypt / ACME)
├── SSH reverse-port tunnels
├── OAuth2 / bearer / signature auth per route
└── OpenRPC JSON-RPC 2.0 management API
│
~/hero/var/sockets/hero_proxy/rpc.sock
Crates
| Crate | Type | Description |
|---|---|---|
hero_proxy |
binary | CLI — registers and starts/stops all services via hero_proc |
hero_proxy_server |
binary | TCP proxy + service discovery + OpenRPC API |
hero_proxy_ui |
binary | Admin dashboard |
hero_proxy_sdk |
library | Auto-generated typed client |
weblib |
library | Reusable web / TLS / ACME library |
Sockets
All sockets under $HERO_SOCKET_DIR/hero_proxy/ (default ~/hero/var/sockets/hero_proxy/).
| Socket | Protocol | Description |
|---|---|---|
rpc.sock |
OpenRPC / JSON-RPC 2.0 | Management API |
ui.sock |
HTTP | Admin dashboard |
Ports (TCP)
| Port | Protocol | Description |
|---|---|---|
| 9997 | HTTP | Proxy ingress (dev / LAN) |
| 9996 | HTTPS | Proxy ingress (TLS) |
| 443 | HTTPS | Production ingress (Let's Encrypt) |
| 80 | HTTP | Redirect → HTTPS (Let's Encrypt mode) |
Service Management (Nushell)
All service lifecycle operations are done through Nushell using the service_proxy and proxy modules from hero_skills.
use services/service_proxy.nu *
use clients/proxy.nu *
Install and start
# Build release binaries, install to ~/hero/bin, register with hero_proc, start
service_proxy install
service_proxy start
Stop / restart
service_proxy stop
service_proxy restart # stop → rebuild → start
Status and logs
service_proxy status # hero_proc list for hero_proxy_*
service_proxy logs # streaming logs from hero_proxy_server
service_proxy logs-ui # streaming logs from hero_proxy_ui
Dev build (faster iteration)
service_proxy start --dev # cargo build (debug), install, start
TLS / ACME Configuration
TLS settings are persisted in the database so they survive restarts without environment variables. DB values always take precedence over env vars.
Set via the management API (recommended)
# Set the domain for Let's Encrypt (required)
proxy system config set --dns-name proxy.example.com
# Set contact email (strongly recommended — expiry notifications)
proxy system config set --acme-email admin@example.com
# Switch to production CA (default is staging — safe to test first)
proxy system config set --acme-production true
# View current effective config and where each value comes from
proxy system config get
# Clear a field (reverts to env var fallback, or unset)
proxy system config remove dns_name
Response from proxy system config get
{
dns_name: "proxy.example.com"
acme_email: "admin@example.com"
acme_production: true
dns_name_source: "db" # db | env | unset
acme_email_source: "db" # db | env | unset
acme_production_source: "db" # db | env | default
}
Env var fallbacks (legacy / alternative)
| DB key (via API) | Environment variable | Default |
|---|---|---|
acme_dns_name |
HERO_PROXY_DNS_NAME |
— (self-signed) |
acme_email |
HERO_PROXY_ACME_EMAIL |
— (no email) |
acme_production |
HERO_PROXY_ACME_PRODUCTION |
false (staging) |
Changes take effect the next time a listener with tls_mode=letsencrypt is started. Running listeners are not hot-reloaded — restart the listener after changing config.
Quick-start: public HTTPS with Let's Encrypt
# 1. Install and start the service
service_proxy install
service_proxy start
# 2. Configure ACME (while service is running — no restart needed for config)
proxy system config set --dns-name proxy.example.com --acme-email admin@example.com
proxy system config set --acme-production true
# 3. Add an HTTPS listener (starts the ACME challenge immediately)
proxy listener add "0.0.0.0:443" --protocol https --tls-mode letsencrypt
# 4. Verify
proxy listener status
proxy tls check proxy.example.com
Quick-start: SSH tunnel to a public server
# Create HTTP + HTTPS + DNS-bridge tunnels in one call and start them
proxy tunnel quick_add edge.example.com admin --auth-key-path ~/.ssh/id_ed25519
# Check status
proxy tunnel status
proxy tunnel check_dns 3
Domain routing
# Route a hostname to a local service socket
proxy domain add app.example.com socket /run/myapp.sock
# Route with bearer-token auth
proxy domain add api.example.com https https://127.0.0.1:9000 --auth-mode bearer
# Route with OAuth (Google)
proxy oauth set google google $CLIENT_ID $CLIENT_SECRET \
--scopes "openid email profile"
proxy domain add dash.example.com http http://127.0.0.1:8080 \
--auth-mode oauth --oauth-provider google
# List / inspect routes
proxy domain list
proxy domain get 3
Development
# Fast check without producing a binary
cargo check -p hero_proxy_server
# Run tests
cargo test
# Clippy
cargo clippy --all-targets -- -D warnings
# Format
cargo fmt
Documentation
- docs/configuration.md — all env vars and DB settings
- docs/api.md — management API reference
- docs/architecture.md — system design
- docs/setup.md — installation and deployment
- docs/releasing.md — release process
The Nushell client reference lives in hero_skills:
tools/modules/clients/proxy.nu— all RPC commandstools/docs/proxy.md— full command reference