feat(membershipd): --bind flag governs HTTP + embedded NATS interface

Add a --bind flag (default 127.0.0.1) to membershipd that controls which
network interface both the control-plane HTTP API and the embedded NATS data
plane listen on. Use 0.0.0.0 to expose the stack to the LAN so remote peers
(phones, other PCs) can connect; keep the default for a loopback-only dev stack.

embeddednats gains StartHost(storeDir, host, port) for explicit interface
control; Start stays a backward-compatible wrapper (host "" = nats default
0.0.0.0) so the playground and tests are untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-06 18:05:05 +02:00
parent 0bd6eb5315
commit 01f8988cc3
2 changed files with 23 additions and 5 deletions
+6 -2
View File
@@ -23,6 +23,7 @@ import (
func main() {
var (
bind = flag.String("bind", "127.0.0.1", "network interface to bind the HTTP API and the embedded NATS to; use 0.0.0.0 to accept LAN/remote peers")
natsURL = flag.String("nats-url", "", "external NATS url; empty starts an embedded server")
httpPort = flag.String("http-port", "8470", "HTTP port for the control-plane API")
dbPath = flag.String("db", "./local_files/unibus.db", "SQLite database path")
@@ -40,7 +41,10 @@ func main() {
natsClientURL := *natsURL
if natsClientURL == "" {
var err error
ns, err = embeddednats.Start(*natsStore, *natsPort)
// Bind the embedded NATS to the same interface as the HTTP API so a single
// --bind flag governs reachability: 127.0.0.1 keeps the whole stack
// loopback-only; 0.0.0.0 exposes both planes to the LAN.
ns, err = embeddednats.StartHost(*natsStore, *bind, *natsPort)
if err != nil {
log.Fatalf("start embedded nats: %v", err)
}
@@ -65,7 +69,7 @@ func main() {
log.Printf("blob store: %s", *storeDir)
srv := membership.NewServer(store, blobs)
addr := "127.0.0.1:" + *httpPort
addr := *bind + ":" + *httpPort
httpSrv := &http.Server{Addr: addr, Handler: srv}
go func() {