Files
theta-suite/spoke.env.example
T
wmantly 455450db1f feat(multi-site): spoke.env.example + CFG_PUBLIC_DOMAIN
A dedicated spoke.env for the join-a-cluster vars (CFG_MASTER_DIRECTORY_URL/
_JOIN_KEY, CFG_SPOKE_NO_INBOUND/_PUBLIC_HOST, CFG_PUBLIC_DOMAIN), split out
of setup.env purely for clarity -- setup.env still has every option and
keeps working as a single file if that's preferred. setup.sh reads both
(setup.env first, spoke.env layered on top so its values win), same
first-run-only rule as setup.env already had.

Also adds CFG_PUBLIC_DOMAIN (documented in MULTI_SITE_SPEC.md §4 but never
actually wired into setup.sh): an inbound spoke/standalone site's own public
web domain, independent of CFG_DOMAIN (the shared LDAP identity namespace,
which must stay identical across every site). Unset behaves exactly as
before -- hostnames derive from CFG_DOMAIN like any standalone install.
2026-08-10 22:22:54 -04:00

55 lines
3.5 KiB
Bash

# ─────────────────────────────────────────────────────────────────────────────
# spoke.env — join this stack to an existing Theta Directory as a read-only
# spoke, instead of seeding a fresh master (MULTI_SITE_SPEC.md).
#
# This is the ONE place the join-a-cluster vars live -- split out of
# setup.env.example (which still has every option, including these, for a
# single-file bring-up) purely for clarity: standing up a spoke is a distinct
# operation from configuring a fresh install, so it gets its own small file
# instead of being buried among unrelated options. Set what you need here;
# everything else (domain, admin creds, SMTP, ...) still comes from setup.env
# as normal -- copy setup.env.example too and fill in CFG_DOMAIN there first.
#
# Same first-run-only rule as setup.env: read once (layered on top of
# setup.env, so a var set in both places takes this file's value), then
# ignored once ./config/ exists -- an already-running directory can never be
# merged into a master's this way. The one exception is the no-inbound relay
# vars at the bottom, which setup.sh re-checks on every run (see their
# comment) since mesh peering usually finishes after the first bring-up.
#
# cp setup.env.example setup.env # if you haven't already -- set CFG_DOMAIN
# cp spoke.env.example spoke.env
# $EDITOR spoke.env # set CFG_MASTER_DIRECTORY_URL + _JOIN_KEY below
# ./setup.sh
#
# Copying this file to spoke.env (gitignored) keeps your join key out of git.
# ─────────────────────────────────────────────────────────────────────────────
# The master's URL and a site join key. Mint a key on the master:
# Directory -> the Master Site modal -> Site Join Keys -> Mint key.
# Both required to join; if either is unset this stack seeds a fresh master
# instead (setup.env.example's normal behavior).
CFG_MASTER_DIRECTORY_URL=https://sso.master.example.com
CFG_MASTER_DIRECTORY_JOIN_KEY=stj_9f2e...
# This spoke's own public web domain, if it needs one independent of the
# master's (an inbound spoke serving its own traffic directly -- see
# CFG_SPOKE_NO_INBOUND below for the opposite case). Optional: CFG_DOMAIN
# (in setup.env) is the shared LDAP identity namespace and must be identical
# across every site in the cluster -- this only changes where THIS site's own
# web hostnames (sso.*, proxy.*) point, never the LDAP base DN.
#CFG_PUBLIC_DOMAIN=branch2.example.com
# No public IP at all (CGNAT, etc.)? The master can still reach this spoke by
# relaying over the gateway-to-gateway WireGuard mesh instead of the open
# internet (MULTI_SITE_SPEC.md §5.2) -- but the mesh peering itself is a
# manual, out-of-band step on BOTH jump-hosts (mint a mesh join token on the
# master's jump-host, paste it into this site's jump-host "Join a mesh" UI
# action) that can't run unattended inside this script. Once that's done, set
# these two and re-run setup.sh: it discovers this jump-host's assigned mesh
# IP and registers it with the master, which then auto-creates the relay
# route on its own theta-proxy. Safe to leave set before meshing -- setup.sh
# just reports "not meshed yet" and skips until a later re-run finds the IP.
#CFG_SPOKE_NO_INBOUND=true
#CFG_SPOKE_PUBLIC_HOST=sso-branch2.master-domain.example.com