feb917fc6a
Roll the --ws-port + --cors-origins flags (issue uniweb/0001) out to the unibus cluster so the browser-native uniweb client can reach the data plane (nats.ws) and the control plane (CORS) on every node. The WS reuses the data-plane TLS (wss://) and the same origin allowlist. Per-node WS port override (WS_PORT_<NAME>): magnus runs unibus_admin on 127.0.0.1:8480, so the bus WS binds 8485 there to avoid a crash-loop; homer and datardos keep 8480. deploy-cluster.sh also gains DEPLOY_ONLY=<name> for rolling one node at a time. Rolled out and verified 2026-06-13: all three nodes healthy, WS reachable, CORS 204, cluster quorum (R3) intact throughout.
71 lines
3.6 KiB
Bash
71 lines
3.6 KiB
Bash
# Cluster topology for the unibus 3-node deployment (issue 0006g).
|
|
#
|
|
# This file is SOURCED by generate-cluster-certs.sh and deploy-cluster.sh.
|
|
#
|
|
# HUMAN: fill in every placeholder with the real value before running the
|
|
# scripts. The public IPs known at authoring time are pre-filled; the WireGuard
|
|
# mesh IPs and magnus's public IP must be supplied. The scripts refuse to run
|
|
# while any unfilled placeholder remains.
|
|
|
|
# Cluster identity (must be identical on every node).
|
|
CLUSTER_NAME="unibus"
|
|
# Route-secret username; the password is NOT here — it lives in a file (see
|
|
# CLUSTER_PASS_FILE in deploy-cluster.sh) so it never lands in argv or git.
|
|
CLUSTER_USER="unibus-cluster"
|
|
|
|
# KV/nonce replication factor. START AT 1 for the initial 1->3 rollout, then raise
|
|
# to 3 IN PLACE (see README "Scale to R3") once all three nodes have joined. Only
|
|
# set this to 3 here after the third node is up and you re-run the KV update.
|
|
KV_REPLICAS=3
|
|
|
|
# Ports (same on every node; the route port is server-to-server only).
|
|
NATS_CLIENT_PORT=4250
|
|
NATS_ROUTE_PORT=6250
|
|
HTTP_PORT=8470
|
|
|
|
# Browser data-plane: WebSocket listener so the browser-native uniweb client
|
|
# (nats.ws) reaches NATS, and the CORS allowlist for its calls to the control
|
|
# plane. WS reuses the data-plane TLS, so it serves wss:// (the cluster runs with
|
|
# TLS). CORS_ORIGINS is a comma-separated list of allowed browser origins (no
|
|
# spaces). Issue uniweb/0001. The node's firewall must allow WS_PORT.
|
|
WS_PORT=8480
|
|
# Per-node WS port override (WS_PORT_<NAME>). magnus runs unibus_admin on
|
|
# 127.0.0.1:8480, so the bus WebSocket cannot bind 0.0.0.0:8480 there — it would
|
|
# crash-loop. magnus therefore serves the browser WS on 8485; homer and datardos
|
|
# keep 8480 (no admin panel). Verified during the 2026-06-13 rollout.
|
|
WS_PORT_MAGNUS=8485
|
|
CORS_ORIGINS="http://localhost:5173"
|
|
|
|
# Remote install layout and SSH login user.
|
|
REMOTE_DIR="/opt/unibus"
|
|
SSH_USER="root"
|
|
|
|
# Which address family the inter-node routes use. "wg" builds --routes from the
|
|
# WireGuard mesh IPs (private server-to-server links, preferred); "public" uses
|
|
# the public IPs. The route layer is always mutual-TLS regardless.
|
|
#
|
|
# DEPLOY DECISION (2026-06-07): set to "public". No WireGuard mesh exists between
|
|
# the three cluster nodes — homer and datardos do not even have the `wg` binary
|
|
# installed, and om's only WG peers are the operator's personal PCs, not the VPS.
|
|
# Rather than stand up a fresh mesh blindly, the routes go over the public IPs,
|
|
# still protected by the separate cluster route CA (mutual-TLS). On magnus (the
|
|
# only node with ufw active) the route port 6250 is restricted to the homer and
|
|
# datardos public IPs; homer/datardos run ufw inactive (Docker hosts) and rely on
|
|
# the route mutual-TLS for 6250.
|
|
ROUTE_NETWORK="public"
|
|
|
|
# One row per node: NAME SSH_HOST PUBLIC_IP WG_IP
|
|
# NAME -> --server-name and the per-node cert filenames (unique).
|
|
# SSH_HOST -> the `ssh ALIAS` alias (see ~/.ssh/config).
|
|
# PUBLIC_IP -> public address; goes in the cert SANs (client-facing data plane).
|
|
# WG_IP -> WireGuard mesh address; cert SAN + route target when ROUTE_NETWORK=wg.
|
|
# NOTE: with ROUTE_NETWORK=public and no WireGuard mesh, the WG_IP column is set to
|
|
# each node's public IP so the cert SAN covers the address actually used by the
|
|
# public routes and no unfilled placeholder remains (scripts refuse to run otherwise).
|
|
# magnus == organic-machine.com == om (135.125.201.30); SSH alias `magnus` enters as root.
|
|
CLUSTER_NODES=(
|
|
"magnus magnus 135.125.201.30 135.125.201.30"
|
|
"homer homer 141.94.69.66 141.94.69.66"
|
|
"datardos dd 51.91.100.142 51.91.100.142"
|
|
)
|