feat(sankofa): public web CT 7806, portal NPM/DNS defaults, Keycloak redirect helper
- Provision/sync scripts and systemd for corporate Next on 7806; IP_SANKOFA_PUBLIC_WEB for apex NPM - Portal stack: NEXTAUTH_URL default portal.sankofa.nexus; NPM fleet + migrate + DNS ordering - keycloak-sankofa-ensure-client-redirects.sh (KEYCLOAK_ADMIN_PASSWORD); .env.master.example hints - Docs: task list, inventory, FQDN/E2E/EXPECTED_WEB_CONTENT, AGENTS pointers Made-with: Cursor
This commit is contained in:
@@ -52,6 +52,14 @@ NPMPLUS_ALLTRA_HYBX_VMID=
|
||||
IP_NPMPLUS_ALLTRA_HYBX=
|
||||
NPM_URL_MIFOS=
|
||||
|
||||
# --- Keycloak Admin API (optional) ---
|
||||
# For scripts/deployment/keycloak-sankofa-ensure-client-redirects.sh — merge portal/admin redirect URIs.
|
||||
# KEYCLOAK_URL=https://keycloak.sankofa.nexus
|
||||
# KEYCLOAK_REALM=master
|
||||
# KEYCLOAK_CLIENT_ID=sankofa-portal
|
||||
# KEYCLOAK_ADMIN=admin
|
||||
# KEYCLOAK_ADMIN_PASSWORD=
|
||||
|
||||
# --- Fastly ---
|
||||
FASTLY_API_TOKEN=
|
||||
|
||||
@@ -159,6 +167,8 @@ SANKOFA_PHOENIX_API_URL=
|
||||
SANKOFA_PHOENIX_CLIENT_ID=
|
||||
SANKOFA_PHOENIX_CLIENT_SECRET=
|
||||
SANKOFA_PHOENIX_TENANT_ID=
|
||||
# Corporate apex (sankofa.nexus) → CT 7806 when provisioned (default in ip-addresses stays portal until set)
|
||||
# IP_SANKOFA_PUBLIC_WEB=192.168.11.63
|
||||
|
||||
# --- Frontend / MetaMask / Explorer ---
|
||||
VITE_WALLETCONNECT_PROJECT_ID=
|
||||
|
||||
@@ -21,11 +21,14 @@ Orchestration for Proxmox VE, Chain 138 (`smom-dbis-138/`), explorers, NPMplus,
|
||||
| Submodule trees clean (CI / post-merge) | `bash scripts/verify/submodules-clean.sh` |
|
||||
| Submodule + explorer remotes | `docs/00-meta/SUBMODULE_HYGIENE.md` |
|
||||
| smom-dbis-138 `.env` in bash scripts | Prefer `source smom-dbis-138/scripts/lib/deployment/dotenv.sh` + `load_deployment_env --repo-root "$PROJECT_ROOT"` (trims RPC URL line endings). From an interactive shell: `source smom-dbis-138/scripts/load-env.sh`. Proxmox root scripts: `source scripts/lib/load-project-env.sh` (also trims common RPC vars). |
|
||||
| Sankofa portal → CT 7801 (build + restart) | `./scripts/deployment/sync-sankofa-portal-7801.sh` (`--dry-run` first); sets `NEXTAUTH_URL` on CT via `sankofa-portal-ensure-nextauth-on-ct.sh` |
|
||||
| Sankofa portal → CT 7801 (build + restart) | `./scripts/deployment/sync-sankofa-portal-7801.sh` (`--dry-run` first); default `NEXTAUTH_URL=https://portal.sankofa.nexus` via `sankofa-portal-ensure-nextauth-on-ct.sh` |
|
||||
| Sankofa corporate web → CT 7806 | Provision: `./scripts/deployment/provision-sankofa-public-web-lxc-7806.sh`. Sync: `./scripts/deployment/sync-sankofa-public-web-to-ct.sh`. systemd: `config/systemd/sankofa-public-web.service`. Set `IP_SANKOFA_PUBLIC_WEB` in `.env`, then `scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh` |
|
||||
| CCIP relay (r630-01 host) | Unit: `config/systemd/ccip-relay.service` → `/etc/systemd/system/ccip-relay.service`; `systemctl enable --now ccip-relay` |
|
||||
| TsunamiSwap VM 5010 check | `./scripts/deployment/tsunamiswap-vm-5010-provision.sh` (inventory only until VM exists) |
|
||||
| The Order portal (`https://the-order.sankofa.nexus`) | OSJ management UI (secure auth); source repo **the_order** at `~/projects/the_order`. NPM upstream defaults to **order-haproxy** CT **10210** (`IP_ORDER_HAPROXY:80`); use `THE_ORDER_UPSTREAM_*` to point at the Sankofa portal if 10210 is down. Provision HAProxy: `scripts/deployment/provision-order-haproxy-10210.sh`. **`www.the-order.sankofa.nexus`** → **301** apex (same as www.sankofa / www.phoenix). |
|
||||
| Portal login + Keycloak systemd + `.env` (prints password once) | `./scripts/deployment/enable-sankofa-portal-login-7801.sh` (`--dry-run` first) |
|
||||
| Keycloak redirect URIs (portal + admin) | `./scripts/deployment/keycloak-sankofa-ensure-client-redirects.sh` — needs `KEYCLOAK_ADMIN_PASSWORD` in `.env` |
|
||||
| NPM TLS for hosts missing certs | `./scripts/request-npmplus-certificates.sh` — optional `CERT_DOMAINS_FILTER='portal\\.sankofa|admin\\.sankofa'` |
|
||||
| Completable (no LAN) | `./scripts/run-completable-tasks-from-anywhere.sh` |
|
||||
| Operator (LAN + secrets) | `./scripts/run-all-operator-tasks-from-lan.sh` (use `--skip-backup` if `NPM_PASSWORD` unset) |
|
||||
| Cloudflare bulk DNS → `PUBLIC_IP` | `./scripts/update-all-dns-to-public-ip.sh` — use **`--dry-run`** and **`--zone-only=sankofa.nexus`** (or `d-bis.org` / `mim4u.org` / `defi-oracle.io`) to limit scope; see script header. Prefer scoped **`CLOUDFLARE_API_TOKEN`** (see `.env.master.example`). |
|
||||
|
||||
@@ -177,6 +177,17 @@ SANKOFA_PHOENIX_API_PORT="${SANKOFA_PHOENIX_API_PORT:-4000}"
|
||||
SANKOFA_PORTAL_PORT="${SANKOFA_PORTAL_PORT:-3000}"
|
||||
IP_SANKOFA_PHOENIX_API="${IP_SANKOFA_PHOENIX_API:-$IP_SERVICE_50}"
|
||||
IP_SANKOFA_PORTAL="${IP_SANKOFA_PORTAL:-$IP_SERVICE_51}"
|
||||
# Corporate apex (sankofa.nexus marketing). Default: same as portal until you set IP_SANKOFA_PUBLIC_WEB in .env (e.g. CT 7806).
|
||||
# CT 7806 (sankofa-public-web) LAN IP when provisioned — see scripts/deployment/provision-sankofa-public-web-lxc-7806.sh
|
||||
IP_SANKOFA_PUBLIC_WEB_CT="${IP_SANKOFA_PUBLIC_WEB_CT:-192.168.11.63}"
|
||||
IP_SANKOFA_PUBLIC_WEB="${IP_SANKOFA_PUBLIC_WEB:-$IP_SANKOFA_PORTAL}"
|
||||
SANKOFA_PUBLIC_WEB_PORT="${SANKOFA_PUBLIC_WEB_PORT:-$SANKOFA_PORTAL_PORT}"
|
||||
# Client SSO apps (portal.sankofa.nexus, admin.sankofa.nexus) — typical: same LXC as hybrid portal (7801).
|
||||
IP_SANKOFA_CLIENT_SSO="${IP_SANKOFA_CLIENT_SSO:-$IP_SANKOFA_PORTAL}"
|
||||
SANKOFA_CLIENT_SSO_PORT="${SANKOFA_CLIENT_SSO_PORT:-$SANKOFA_PORTAL_PORT}"
|
||||
# Operator dash (dash.sankofa.nexus). Leave unset to skip creating/updating dash in NPM fleet script until provisioned.
|
||||
# IP_SANKOFA_DASH="192.168.11.xx"
|
||||
# SANKOFA_DASH_PORT="${SANKOFA_DASH_PORT:-3000}"
|
||||
|
||||
# Gov Portals dev (VMID 7804) — DBIS, ICCC, OMNL, XOM at *.xom-dev.phoenix.sankofa.nexus
|
||||
IP_GOV_PORTALS_DEV="192.168.11.54"
|
||||
|
||||
17
config/systemd/sankofa-public-web.service
Normal file
17
config/systemd/sankofa-public-web.service
Normal file
@@ -0,0 +1,17 @@
|
||||
[Unit]
|
||||
Description=Sankofa corporate public web (Next.js root app) for sankofa.nexus
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/sankofa-public-web
|
||||
Environment=NODE_ENV=production
|
||||
Environment=PORT=3000
|
||||
# Use login shell so corepack/pnpm PATH matches interactive CT admin.
|
||||
ExecStart=/bin/bash -lc 'cd /opt/sankofa-public-web && exec pnpm start'
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -1,7 +1,7 @@
|
||||
# Web Properties — Ground Truth & Validation
|
||||
|
||||
**Last Updated:** 2026-03-27
|
||||
**Document Version:** 1.5
|
||||
**Last Updated:** 2026-03-29
|
||||
**Document Version:** 1.6
|
||||
**Status:** Active Documentation
|
||||
|
||||
---
|
||||
@@ -314,17 +314,17 @@ Backend (typical):
|
||||
| Service | Domain | VMID | IP | Port | Status | Access model |
|
||||
|---------|--------|------|-----|------|--------|----------------|
|
||||
| **Phoenix** (API today; division hostname) | phoenix.sankofa.nexus | 7800 | 192.168.11.50 | 4000 | ✅ Active | Public web **intent**; API paths coexist |
|
||||
| **Sankofa public web** | sankofa.nexus | 7801 | 192.168.11.51 | 3000 | ✅ Active | Public **intent** (see hostname model) |
|
||||
| **Sankofa public web** | sankofa.nexus | **7806** @ `192.168.11.63` (or **`IP_SANKOFA_PUBLIC_WEB`** in `.env`) | **`IP_SANKOFA_PUBLIC_WEB`** | **`SANKOFA_PUBLIC_WEB_PORT`** (`3000`) | ✅ Active | Provision: `provision-sankofa-public-web-lxc-7806.sh`; sync: `sync-sankofa-public-web-to-ct.sh`; NPM fleet script |
|
||||
| **The Order (edge)** | the-order.sankofa.nexus | 10210 → 7801 | 192.168.11.39:80 → .51:3000 | 80 → 3000 | ✅ Active | HAProxy then portal; see §2b |
|
||||
| **Sankofa Studio** | studio.sankofa.nexus | 7805 | 192.168.11.72 | 8000 | ✅ Active | `/studio/` |
|
||||
| **Keycloak IdP** | keycloak.sankofa.nexus | 7802 | (see ALL_VMIDS) | 8080 | ✅ Active | IdP + `/admin` |
|
||||
| **Client admin (SSO)** | admin.sankofa.nexus | — | — | — | 🔶 **Intent** — NPM + app upstream not pinned in VM inventory; may share portal stack (**7801**) until split (see §4, Open Decisions §4) | SSO |
|
||||
| **Client portal (SSO)** | portal.sankofa.nexus | **7801** (typical) | 192.168.11.51 | 3000 | ✅ **Active** when NPM routes this hostname to the Sankofa portal stack; `NEXTAUTH_URL` / public OIDC URL per `scripts/deployment/sync-sankofa-portal-7801.sh` | SSO |
|
||||
| **Operator dash** | dash.sankofa.nexus | — | — | — | 🔶 **Intent** — IP allowlist + system auth + MFA; **VMID/IP not fixed** in this matrix until NPM/upstream is wired (see §6) | IP + MFA |
|
||||
| **Client admin (SSO)** | admin.sankofa.nexus | **7801** (typical) | 192.168.11.51 | 3000 | ✅ **NPM row** in fleet script (shares **`IP_SANKOFA_CLIENT_SSO`** with portal until split) | SSO |
|
||||
| **Client portal (SSO)** | portal.sankofa.nexus | **7801** (typical) | 192.168.11.51 | 3000 | ✅ **NPM row** in fleet script; default **`NEXTAUTH_URL=https://portal.sankofa.nexus`** (`sync-sankofa-portal-7801.sh`) | SSO |
|
||||
| **Operator dash** | dash.sankofa.nexus | — | **`IP_SANKOFA_DASH`** (when set) | **`SANKOFA_DASH_PORT`** | 🔶 **Fleet script** adds NPM upstream only when **`IP_SANKOFA_DASH`** set; app + IP allowlist + MFA still operator work (see §6) | IP + MFA |
|
||||
| **SolaceScanScout** | explorer.d-bis.org | 5000 | 192.168.11.140 | 80/4000 | ✅ Active | Public |
|
||||
| **Blockscout (generic hostname)** | blockscout.defi-oracle.io | **5000** | 192.168.11.140 | **80** (TLS at NPM) | ✅ **Active** when NPM proxies here; **same class** of Blockscout UI as §7 but **not** canonical **SolaceScanScout / Chain 138** branding (see §8) | Public |
|
||||
|
||||
**Table notes:** `admin` / `dash` rows stay **non-numeric** on VMID until inventory and NPM proxy rows are authoritative in [ALL_VMIDS_ENDPOINTS.md](../04-configuration/ALL_VMIDS_ENDPOINTS.md) and your NPM export. **`blockscout.defi-oracle.io`** has been documented in routing summaries as terminating on **VMID 5000** (`192.168.11.140:80`); confirm live NPM if behavior differs.
|
||||
**Table notes:** `dash` **VMID** stays **TBD** until an operator app is pinned; set **`IP_SANKOFA_DASH`** in `config/ip-addresses.conf` to create/update the NPM proxy via `update-npmplus-proxy-hosts-api.sh`. **`admin`** / **`portal`** share **7801** in the default config. Confirm live NPM + DNS + Keycloak redirect URIs after each change. **`blockscout.defi-oracle.io`**: see [ALL_VMIDS_ENDPOINTS.md](../04-configuration/ALL_VMIDS_ENDPOINTS.md).
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
# Sankofa and Phoenix — public, portal, and system admin endpoint correction tasks
|
||||
|
||||
**Created:** 2026-03-29
|
||||
**Purpose:** Ordered checklist to align **DNS, NPM upstreams, deployed apps, auth URLs, and inventory** with the hostname model in [EXPECTED_WEB_CONTENT.md](../02-architecture/EXPECTED_WEB_CONTENT.md) and [FQDN_EXPECTED_CONTENT.md](../04-configuration/FQDN_EXPECTED_CONTENT.md).
|
||||
**Verify:** [E2E_ENDPOINTS_LIST.md](../04-configuration/E2E_ENDPOINTS_LIST.md), `scripts/verify/verify-end-to-end-routing.sh --profile=public` (from LAN).
|
||||
|
||||
---
|
||||
|
||||
## Target state (summary)
|
||||
|
||||
| Hostname | Tier | Expected content |
|
||||
|----------|------|------------------|
|
||||
| `sankofa.nexus` / `www` | Public web | Corporate / brand (Sankofa — Sovereign Technologies), unauthenticated marketing pages. |
|
||||
| `phoenix.sankofa.nexus` / `www` | Public web (+ API) | Phoenix Cloud Services division web (intent); API paths may coexist until split. |
|
||||
| `portal.sankofa.nexus` | Client SSO | Hybrid cloud / client workspace, marketplace, NextAuth + Keycloak with **public URL = this host**. |
|
||||
| `admin.sankofa.nexus` | Client SSO | Client access administration (IAM-style); not Keycloak operator `/admin`. |
|
||||
| `keycloak.sankofa.nexus` | IdP | Realm login, tokens, well-known; operator console at `/admin`. |
|
||||
| `dash.sankofa.nexus` | Operator / systems | IP allowlist + system auth + MFA; not client self-service. |
|
||||
| `the-order.sankofa.nexus` | Program portal | OSJ / Order app; edge 10210 (HAProxy) → appropriate upstream. |
|
||||
| `studio.sankofa.nexus` | Tooling | Sankofa Studio (7805), `/studio/`. |
|
||||
|
||||
**Remaining operator work:** Add **DNS A/AAAA** records for `portal.sankofa.nexus` and `admin.sankofa.nexus` (and `dash` when used). Run **`scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh`** from LAN with `NPM_PASSWORD`, assign **SSL** in NPM for new rows, and update **Keycloak** client redirect URIs for `https://portal.sankofa.nexus/*` (and `admin` if distinct). Provision **CT 7806** (or set **`IP_SANKOFA_PUBLIC_WEB`**) when the corporate site should no longer share the portal binary on apex.
|
||||
|
||||
---
|
||||
|
||||
## Implementation status (repo — 2026-03-29)
|
||||
|
||||
| Item | Done in repo |
|
||||
|------|----------------|
|
||||
| NPM fleet script: `portal` / `admin` / conditional `dash` | `scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh` |
|
||||
| NPM migrate script + Sankofa ID script | `migrate-to-npmplus.sh`, `update-sankofa-npmplus-proxy-hosts.sh` (apex uses `IP_SANKOFA_PUBLIC_WEB`) |
|
||||
| Config vars | `config/ip-addresses.conf`: `IP_SANKOFA_PUBLIC_WEB`, `SANKOFA_PUBLIC_WEB_PORT`, `IP_SANKOFA_CLIENT_SSO`, `SANKOFA_CLIENT_SSO_PORT`, optional `IP_SANKOFA_DASH` |
|
||||
| Default `NEXTAUTH_URL` for portal | `sync-sankofa-portal-7801.sh`, `sankofa-portal-ensure-nextauth-on-ct.sh`, `enable-sankofa-portal-login-7801.sh` → **`https://portal.sankofa.nexus`** |
|
||||
| Corporate site deploy path | `scripts/deployment/sync-sankofa-public-web-to-ct.sh` + `config/systemd/sankofa-public-web.service` |
|
||||
| Inventory / index | `ALL_VMIDS_ENDPOINTS.md`, `AGENTS.md`, `MASTER_INDEX.md` (task list row) |
|
||||
|
||||
**Not automatable here:** Keycloak **realm client** redirect URI edits (operator console), provisioning CT **7806** for corporate apex split, Phoenix marketing page on **7800**, operator **dash** app + **`IP_SANKOFA_DASH`**, NPM **IP allowlists** for dash, stakeholder sign-off.
|
||||
|
||||
**Operator run (2026-03-29, LAN):** Loaded `.env` (`NPM_PASSWORD`, Cloudflare). Ran `update-npmplus-proxy-hosts-api.sh` (added NPM rows **portal** / **admin**). Ran `sankofa-portal-ensure-nextauth-on-ct.sh` + full `sync-sankofa-portal-7801.sh`. Ran `update-all-dns-to-public-ip.sh --zone-only=sankofa.nexus` (new A records **portal**, **admin**, **keycloak**; **studio** updated). E2E `verify-end-to-end-routing.sh --profile=public` exit `0`; evidence: `docs/04-configuration/verification-evidence/e2e-verification-20260329_045318/` (and `045210/`). **7806** provisioned **2026-03-29** on r630-01 @ **192.168.11.63**; corporate site synced; NPM **sankofa.nexus** / **www** → **.63:3000** when `.env` sets **`IP_SANKOFA_PUBLIC_WEB=192.168.11.63`** (operator machine). Ran `request-npmplus-certificates.sh` with `CERT_DOMAINS_FILTER` for **portal.sankofa.nexus** and **admin.sankofa.nexus**; NPM certificate IDs **180** / **179** assigned with **SSL forced**; HTTPS smoke **200**. **Keycloak:** set `KEYCLOAK_ADMIN_PASSWORD` in `.env` and run `scripts/deployment/keycloak-sankofa-ensure-client-redirects.sh`, or add **Valid redirect URIs** / **Web origins** in the console for **portal** and **admin** (client **sankofa-portal**, realm **master** per portal `.env` template).
|
||||
|
||||
---
|
||||
|
||||
## Phase 0 — Decisions and inventory (blockers)
|
||||
|
||||
1. **Confirm split strategy for 7801**
|
||||
- **Option A:** Second CT/VM (new VMID) for **public marketing** Next app; keep **7801** for **`portal`/`admin`** only.
|
||||
- **Option B:** Single process with host-based routing (middleware) — higher risk; only if product accepts shared runtime.
|
||||
- Document chosen VMID(s), ports, and systemd unit names in [ALL_VMIDS_ENDPOINTS.md](../04-configuration/ALL_VMIDS_ENDPOINTS.md).
|
||||
|
||||
2. **Resolve Phoenix “public web vs API”** (open decision in EXPECTED_WEB_CONTENT)
|
||||
- Either add **static/marketing** upstream or **path-based** split on 7800, or dedicate a small VM for Phoenix marketing.
|
||||
- Record **browser-default** behavior for `GET /` on `phoenix.sankofa.nexus` (not only `/health` / GraphQL).
|
||||
|
||||
3. **Pin `admin` and `dash` targets**
|
||||
- **admin:** same app as portal (path prefix), separate deploy, or separate repo — decide and record IP:port / VMID.
|
||||
- **dash:** choose app (existing vs greenfield), VMID, IP:port, MFA method, and **NPM IP allowlist** / VPN-only DNS policy.
|
||||
|
||||
4. **Keycloak clients**
|
||||
- For each public hostname that uses OIDC (`portal`, `admin`, and any others), register **valid redirect URIs** and **web origins** for the **final** URLs (not interim apex).
|
||||
|
||||
---
|
||||
|
||||
## Phase 1 — Sankofa public apex (`sankofa.nexus`)
|
||||
|
||||
5. **Build and deploy corporate site** from **`Sankofa` repo root** (not `Sankofa/portal`): `src/app`, `public/`, root `package.json` / `next.config.js`.
|
||||
6. **Provision runtime** on the chosen host (new CT or existing): Node/pnpm, systemd (or container), production `pnpm build` + `pnpm start`, listen port (e.g. 3000).
|
||||
7. **Point NPM** `sankofa.nexus` and `www.sankofa.nexus` → **new public-site upstream** (update `update-npmplus-proxy-hosts-api.sh`, `update-sankofa-npmplus-proxy-hosts.sh`, `migrate-to-npmplus.sh` as needed).
|
||||
8. **Remove portal-only behavior from apex** (no forced login shell on `/` for anonymous users unless product explicitly wants a teaser).
|
||||
9. **Smoke test:** anonymous `GET https://sankofa.nexus/` shows marketing; links to `phoenix`, `portal`, `the-order` work.
|
||||
|
||||
---
|
||||
|
||||
## Phase 2 — Client portal (`portal.sankofa.nexus`)
|
||||
|
||||
10. **Ensure NPM proxy host** `portal.sankofa.nexus` exists and points to **portal** upstream (today typically **192.168.11.51:3000** / 7801 if portal stays there). Add lines to `update-npmplus-proxy-hosts-api.sh` (and sibling updaters).
|
||||
11. **Set NextAuth / OIDC public URL** to `https://portal.sankofa.nexus`:
|
||||
- `SANKOFA_PORTAL_NEXTAUTH_URL=https://portal.sankofa.nexus` when running `sync-sankofa-portal-7801.sh` and `sankofa-portal-ensure-nextauth-on-ct.sh`.
|
||||
- Update defaults in script headers/comments so operators are not steered to apex.
|
||||
12. **Update `Sankofa/portal`** `.env.example` / README: replace `NEXTAUTH_URL=https://sankofa.nexus` with **`https://portal.sankofa.nexus`**.
|
||||
13. **Keycloak:** client `redirect_uri` / `Valid Redirect URIs` must include `https://portal.sankofa.nexus/*` (and dev hosts if any).
|
||||
14. **Cookie / CSRF:** confirm `NEXTAUTH_URL` matches browser bar; fix any `localhost` or apex leakage in callbacks.
|
||||
|
||||
---
|
||||
|
||||
## Phase 3 — Client admin (`admin.sankofa.nexus`)
|
||||
|
||||
15. **Implement or wire** the admin UI (if not already a route in portal app, add app or path and deploy target).
|
||||
16. **NPM:** add `admin.sankofa.nexus` → upstream (may equal portal VM until split).
|
||||
17. **OIDC:** separate Keycloak client or fine-grained roles; redirect URIs for `https://admin.sankofa.nexus/*`.
|
||||
18. **Document** in ALL_VMIDS_ENDPOINTS + EXPECTED_WEB_CONTENT deployment table (replace “intent / TBD” with IP:port).
|
||||
|
||||
---
|
||||
|
||||
## Phase 4 — Operator systems admin (`dash.sankofa.nexus`)
|
||||
|
||||
19. **Deploy** dash application to chosen VMID with **MFA** and **strong session** policy.
|
||||
20. **NPM:** create `dash.sankofa.nexus` proxy; attach **IP allowlist** (NPM access list / firewall) per EXPECTED_WEB_CONTENT.
|
||||
21. **DNS:** restrict resolution to operator networks if policy requires (optional; often IP block at edge is enough).
|
||||
22. **Inventory:** pin VMID, IP, port in ALL_VMIDS_ENDPOINTS and FQDN_EXPECTED_CONTENT.
|
||||
|
||||
---
|
||||
|
||||
## Phase 5 — Phoenix public (`phoenix.sankofa.nexus`)
|
||||
|
||||
23. **Deliver browser-facing division home** (or documented interim: redirect to docs / status page) consistent with FQDN_EXPECTED_CONTENT.
|
||||
24. **Preserve API** (`/health`, `/graphql`, etc.) for monitors and clients; avoid breaking E2E `/health` checks.
|
||||
25. **NPM / headers:** ensure WebSocket or long-lived connections if GraphQL subscriptions are exposed on same host.
|
||||
26. **Copy and nav:** corporate site links “Phoenix” to this hostname, not to portal.
|
||||
|
||||
---
|
||||
|
||||
## Phase 6 — Program and tooling hostnames (sanity)
|
||||
|
||||
27. **the-order.sankofa.nexus:** confirm HAProxy **10210** → correct upstream; if Order app diverges from generic portal, point backend to **the_order** build instead of 7801 generic portal (per product).
|
||||
28. **studio.sankofa.nexus:** confirm 7805 `/studio/`; certificate and upstream unchanged unless Studio moves.
|
||||
29. **www.*:** confirm **301** to apex for `sankofa`, `phoenix`, `the-order` in NPM `advanced_config`.
|
||||
|
||||
---
|
||||
|
||||
## Phase 7 — Automation, docs, and regression
|
||||
|
||||
30. ~~**Scripts:** extend fleet NPM updater~~ **Done:** `update-npmplus-proxy-hosts-api.sh`, `migrate-to-npmplus.sh`, `update-sankofa-npmplus-proxy-hosts.sh` + `config/ip-addresses.conf`.
|
||||
31. ~~**Corporate sync script**~~ **Done:** `scripts/deployment/sync-sankofa-public-web-to-ct.sh` + `config/systemd/sankofa-public-web.service`.
|
||||
32. **E2E:** after DNS + NPM SSL for `portal` / `admin` (and `dash` when live), move hosts from “optional when fail” to **required** in `verify-end-to-end-routing.sh` / tighten `E2E_OPTIONAL_WHEN_FAIL`.
|
||||
33. ~~**EXPECTED_WEB_CONTENT.md** table~~ **Partially done:** `admin` / `portal` NPM rows documented; **`dash`** stays 🔶 until app + **`IP_SANKOFA_DASH`**; apex row notes **7806** / `IP_SANKOFA_PUBLIC_WEB`.
|
||||
34. **Run** `verify-end-to-end-routing.sh --profile=public` from LAN; archive evidence under `docs/04-configuration/verification-evidence/`.
|
||||
35. **Stakeholder sign-off:** security review of public vs SSO vs operator boundaries and Keycloak client surface area.
|
||||
|
||||
---
|
||||
|
||||
## Quick dependency graph
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
D0[Phase 0 decisions] --> P1[Phase 1 apex public]
|
||||
D0 --> P2[Phase 2 portal host]
|
||||
D0 --> P3[Phase 3 admin]
|
||||
D0 --> P4[Phase 4 dash]
|
||||
D0 --> P5[Phase 5 Phoenix web]
|
||||
P2 --> KC[Keycloak client URIs]
|
||||
P3 --> KC
|
||||
P1 --> NPM[NPM / DNS updates]
|
||||
P2 --> NPM
|
||||
P3 --> NPM
|
||||
P4 --> NPM
|
||||
P5 --> NPM
|
||||
NPM --> E2E[Phase 7 E2E + docs]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## References (repo)
|
||||
|
||||
- Hostname model: [EXPECTED_WEB_CONTENT.md](../02-architecture/EXPECTED_WEB_CONTENT.md)
|
||||
- FQDN matrix: [FQDN_EXPECTED_CONTENT.md](../04-configuration/FQDN_EXPECTED_CONTENT.md)
|
||||
- IPs / VMIDs: [ALL_VMIDS_ENDPOINTS.md](../04-configuration/ALL_VMIDS_ENDPOINTS.md)
|
||||
- NPM API updater: `scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh`
|
||||
- Portal deploy: `scripts/deployment/sync-sankofa-portal-7801.sh`, `scripts/deployment/sankofa-portal-ensure-nextauth-on-ct.sh`
|
||||
- Corporate web deploy: `scripts/deployment/sync-sankofa-public-web-to-ct.sh`
|
||||
- Order edge: `scripts/deployment/provision-order-haproxy-10210.sh`
|
||||
- Source trees (operator workstation): `../Sankofa` (public site root), `../Sankofa/portal` (client portal), `~/projects/the_order` (Order UI)
|
||||
@@ -1,6 +1,6 @@
|
||||
# Complete VMID and Endpoints Reference
|
||||
|
||||
**Last Updated:** 2026-03-26
|
||||
**Last Updated:** 2026-03-29
|
||||
**Document Version:** 1.2
|
||||
**Status:** Active Documentation — **Master (source of truth)** for VMID, IP, port, and domain mapping. See [MASTER_DOCUMENTATION_INDEX.md](../00-meta/MASTER_DOCUMENTATION_INDEX.md).
|
||||
|
||||
@@ -211,6 +211,22 @@ The following VMIDs have been permanently removed:
|
||||
|
||||
---
|
||||
|
||||
### Hyperledger Aries / AnonCreds
|
||||
|
||||
| VMID | IP Address | Hostname | Status | Endpoints | Purpose |
|
||||
|------|------------|----------|--------|-----------|---------|
|
||||
| 6500 | 192.168.11.88 | aries-1 | ✅ Running | ACA-Py DIDComm: 8030, Admin API: 8031 | Hyperledger Aries / AnonCreds agent runtime |
|
||||
|
||||
---
|
||||
|
||||
### Hyperledger Caliper
|
||||
|
||||
| VMID | IP Address | Hostname | Status | Endpoints | Purpose |
|
||||
|------|------------|----------|--------|-----------|---------|
|
||||
| 6600 | 192.168.11.93 | caliper-1 | ✅ Running | Local CLI workspace, outbound RPC to 192.168.11.211:8545 / 8546 | Hyperledger Caliper benchmark harness |
|
||||
|
||||
---
|
||||
|
||||
### DBIS Core Services
|
||||
|
||||
| VMID | IP Address | Hostname | Status | Endpoints | Purpose |
|
||||
@@ -256,15 +272,17 @@ The following VMIDs have been permanently removed:
|
||||
| VMID | IP Address | Hostname | Status | Endpoints | Purpose |
|
||||
|------|------------|----------|--------|-----------|---------|
|
||||
| 7800 | 192.168.11.50 | sankofa-api-1 | ✅ Running | GraphQL: 4000, Health: /health | Phoenix API (Cloud Platform Portal) |
|
||||
| 7801 | 192.168.11.51 | sankofa-portal-1 | ✅ Running | Web: 3000 | Sankofa Portal (Company Website) |
|
||||
| 7801 | 192.168.11.51 | sankofa-portal-1 | ✅ Running | Web: 3000 | Hybrid cloud **client portal** (`portal.sankofa.nexus` / `admin.sankofa.nexus` when NPM routes); not the long-term corporate apex app — see `IP_SANKOFA_PUBLIC_WEB` / `sync-sankofa-public-web-to-ct.sh` |
|
||||
| 7802 | 192.168.11.52 | sankofa-keycloak-1 | ✅ Running | Keycloak: 8080, Admin: /admin | Identity and Access Management |
|
||||
| 7803 | 192.168.11.53 | sankofa-postgres-1 | ✅ Running | PostgreSQL: 5432 | Database Service |
|
||||
| 7804 | 192.168.11.54 | (Gov Portals dev) | ✅ Running | Web: 80 | Gov Portals — DBIS, ICCC, OMNL, XOM (*.xom-dev.phoenix.sankofa.nexus) |
|
||||
| 7805 | 192.168.11.72 | sankofa-studio | — | API: 8000 | Sankofa Studio (FusionAI Creator) — studio.sankofa.nexus (IP .72; .55 = VMID 10230 order-vault) |
|
||||
| 7806 | 192.168.11.63 | sankofa-public-web | ✅ Running | Web: 3000 | Corporate / marketing Next.js (Sankofa **repo root**); provision: `scripts/deployment/provision-sankofa-public-web-lxc-7806.sh`; deploy: `scripts/deployment/sync-sankofa-public-web-to-ct.sh`; NPM apex via **`IP_SANKOFA_PUBLIC_WEB`** (`.env` or override) |
|
||||
|
||||
**Public Domains** (NPMplus routing):
|
||||
- `sankofa.nexus` → Routes to `http://192.168.11.51:3000` (Sankofa Portal/VMID 7801) ✅
|
||||
- `www.sankofa.nexus` → Same upstream as apex; NPM **`advanced_config`** issues **301** to **`https://sankofa.nexus`** (preserve path/query via `$request_uri`). ✅
|
||||
- `sankofa.nexus` / `www.sankofa.nexus` → **`IP_SANKOFA_PUBLIC_WEB`:`SANKOFA_PUBLIC_WEB_PORT** (typical: **7806** `192.168.11.63:3000` when `.env` sets `IP_SANKOFA_PUBLIC_WEB`; else defaults to portal **7801**); fleet script: `scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh`. **`www`** → **301** → apex `https://sankofa.nexus` (`$request_uri`). ✅
|
||||
- `portal.sankofa.nexus` / `admin.sankofa.nexus` → **`IP_SANKOFA_CLIENT_SSO`:`SANKOFA_CLIENT_SSO_PORT** (typical: 7801 `:3000`). NextAuth / OIDC public URL: **`https://portal.sankofa.nexus`**. ✅ when NPM proxy rows exist (fleet script creates/updates them).
|
||||
- `dash.sankofa.nexus` → Set **`IP_SANKOFA_DASH`** (+ `SANKOFA_DASH_PORT`) in `config/ip-addresses.conf` to enable upstream in the fleet script; IP allowlist at NPM is operator policy. 🔶 until dash app + env are set.
|
||||
- `phoenix.sankofa.nexus` → Routes to `http://192.168.11.50:4000` (Phoenix API/VMID 7800) ✅
|
||||
- `www.phoenix.sankofa.nexus` → Same upstream; **301** to **`https://phoenix.sankofa.nexus`**. ✅
|
||||
- `the-order.sankofa.nexus` / `www.the-order.sankofa.nexus` → OSJ management portal (secure auth). App source: **the_order** at `~/projects/the_order`. NPMplus default upstream: **order-haproxy** `http://192.168.11.39:80` (VMID **10210**), which proxies to Sankofa portal `http://192.168.11.51:3000` (7801). Fallback: set `THE_ORDER_UPSTREAM_IP` / `THE_ORDER_UPSTREAM_PORT` to `.51` / `3000` if HAProxy is offline. **`www.the-order.sankofa.nexus`** → **301** **`https://the-order.sankofa.nexus`** (same as `www.sankofa` / `www.phoenix`).
|
||||
@@ -520,8 +538,11 @@ This section lists all endpoints that should be configured in NPMplus, extracted
|
||||
| `secure.mim4u.org` | `192.168.11.37` | `http` | `80` | ❌ No | MIM4U Secure Portal (VMID 7810) |
|
||||
| `training.mim4u.org` | `192.168.11.37` | `http` | `80` | ❌ No | MIM4U Training Portal (VMID 7810) |
|
||||
| **Sankofa Phoenix Services** |
|
||||
| `sankofa.nexus` | `192.168.11.51` | `http` | `3000` | ❌ No | Sankofa Portal - Company Website (VMID 7801) ✅ **Deployed** |
|
||||
| `www.sankofa.nexus` | `192.168.11.51` | `http` | `3000` | ❌ No | Sankofa Portal (VMID 7801) ✅ **Deployed** |
|
||||
| `sankofa.nexus` | **`IP_SANKOFA_PUBLIC_WEB`** (default `.51` until public-web CT) | `http` | **`SANKOFA_PUBLIC_WEB_PORT`** (`3000`) | ❌ No | Corporate apex; fleet script `update-npmplus-proxy-hosts-api.sh` |
|
||||
| `www.sankofa.nexus` | same as apex | `http` | same | ❌ No | **301** → `https://sankofa.nexus` |
|
||||
| `portal.sankofa.nexus` | **`IP_SANKOFA_CLIENT_SSO`** (typ. `.51` / 7801) | `http` | **`SANKOFA_CLIENT_SSO_PORT`** (`3000`) | ❌ No | Client SSO portal; `NEXTAUTH_URL=https://portal.sankofa.nexus` |
|
||||
| `admin.sankofa.nexus` | same as portal | `http` | same | ❌ No | Client access admin (same upstream until split) |
|
||||
| `dash.sankofa.nexus` | **`IP_SANKOFA_DASH`** (set in `ip-addresses.conf`) | `http` | **`SANKOFA_DASH_PORT`** | ❌ No | Operator dash — row omitted from fleet script until `IP_SANKOFA_DASH` set |
|
||||
| `phoenix.sankofa.nexus` | `192.168.11.50` | `http` | `4000` | ❌ No | Phoenix API - Cloud Platform Portal (VMID 7800) ✅ **Deployed** |
|
||||
| `www.phoenix.sankofa.nexus` | `192.168.11.50` | `http` | `4000` | ❌ No | Phoenix API (VMID 7800) ✅ **Deployed** |
|
||||
| `the-order.sankofa.nexus`, `www.the-order.sankofa.nexus` | `192.168.11.39` (10210 HAProxy; default) or `192.168.11.51` (direct portal if env override) | `http` | `80` or `3000` | ❌ No | NPM → **.39:80** by default; HAProxy → **.51:3000** |
|
||||
@@ -537,9 +558,7 @@ Some domains use path-based routing in NPM configs:
|
||||
- `/graph` → `http://192.168.11.155:3000` (DBIS GraphQL)
|
||||
- `/` → `http://192.168.11.130:80` (DBIS Frontend)
|
||||
|
||||
**`sankofa.nexus`** (per deploy script):
|
||||
- `/api` → `http://10.160.0.10:4000` (Sankofa API)
|
||||
- `/` → `http://10.160.0.11:3000` (Sankofa Portal)
|
||||
**`sankofa.nexus`** (intent): corporate marketing at **`IP_SANKOFA_PUBLIC_WEB`**; **`portal.sankofa.nexus`** serves the authenticated portal at **`IP_SANKOFA_CLIENT_SSO`**. Legacy path-based splits (if any) should be reconciled with [EXPECTED_WEB_CONTENT.md](../02-architecture/EXPECTED_WEB_CONTENT.md).
|
||||
|
||||
**Note**: NPMplus may need custom location blocks or separate proxy hosts for path-based routing.
|
||||
|
||||
@@ -550,7 +569,9 @@ Some domains use path-based routing in NPM configs:
|
||||
| Domain | Correct target (VMID, IP:port) | Do NOT point to |
|
||||
|--------|--------------------------------|-----------------|
|
||||
| `explorer.d-bis.org` | 5000, 192.168.11.140:80 (web), :4000 (API) | — |
|
||||
| `sankofa.nexus`, `www.sankofa.nexus` | 7801, 192.168.11.51:3000 | 192.168.11.140 (Blockscout) |
|
||||
| `sankofa.nexus`, `www.sankofa.nexus` | **Public web:** target **7806** (or `IP_SANKOFA_PUBLIC_WEB`) when split; defaults still **7801**, 192.168.11.51:3000 | 192.168.11.140 (Blockscout) |
|
||||
| `portal.sankofa.nexus`, `admin.sankofa.nexus` | **7801**, 192.168.11.51:3000 (`IP_SANKOFA_CLIENT_SSO`) | 192.168.11.140 (Blockscout) |
|
||||
| `dash.sankofa.nexus` | Set **`IP_SANKOFA_DASH`** when operator dash exists | 192.168.11.140 (Blockscout) |
|
||||
| `phoenix.sankofa.nexus`, `www.phoenix.sankofa.nexus` | 7800, 192.168.11.50:4000 | 192.168.11.140 (Blockscout) |
|
||||
| `the-order.sankofa.nexus`, `www.the-order.sankofa.nexus` | 10210, 192.168.11.39:80 | 192.168.11.140 (Blockscout) |
|
||||
| `studio.sankofa.nexus` | 7805, 192.168.11.72:8000 | — |
|
||||
@@ -561,7 +582,7 @@ If NPMplus proxy hosts for sankofa.nexus or phoenix.sankofa.nexus currently poin
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2026-03-27
|
||||
**Last Updated**: 2026-03-29
|
||||
**Maintained By**: Infrastructure Team
|
||||
|
||||
---
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
|
||||
**What each hostname should present (operator narrative):** [FQDN_EXPECTED_CONTENT.md](FQDN_EXPECTED_CONTENT.md).
|
||||
|
||||
**Latest verified public pass:** `2026-03-27` via `bash scripts/verify/verify-end-to-end-routing.sh --profile=public` with report at [verification_report.md](verification-evidence/e2e-verification-20260327_134032/verification_report.md). Result: exit `0`, `DNS passed: 38`, `Failed: 0`, `HTTPS passed: 19`, `Skipped / optional: 1` (after `run-all-operator-tasks-from-lan.sh` NPM sync; `rpc.defi-oracle.io` may log HTTP 405 on the verifier probe but stays non-failing for the profile).
|
||||
**Latest verified public pass:** `2026-03-29` via `bash scripts/verify/verify-end-to-end-routing.sh --profile=public` with report at [verification_report.md](verification-evidence/e2e-verification-20260329_045318/verification_report.md). Result: exit `0`, `DNS passed: 42`, `Failed: 0`, `HTTPS passed: 27`, `Skipped / optional: 2` (NPM fleet + sankofa zone DNS for `portal` / `admin` / `keycloak`, portal sync + NextAuth on 7801).
|
||||
**Earlier same day:** [verification_report.md](verification-evidence/e2e-verification-20260329_045210/verification_report.md). **Previous:** `2026-03-27` — [verification_report.md](verification-evidence/e2e-verification-20260327_134032/verification_report.md).
|
||||
**Latest verified private/admin pass:** `2026-03-27` via `bash scripts/verify/verify-end-to-end-routing.sh --profile=private` with report at [verification_report.md](verification-evidence/e2e-verification-20260327_134137/verification_report.md). Result: exit `0`, `DNS passed: 4`, `Failed: 0`.
|
||||
|
||||
**Evidence folders:** Each run creates `verification-evidence/e2e-verification-YYYYMMDD_HHMMSS/`. Commit the runs you want on record; older dirs can be removed locally to reduce noise (`scripts/maintenance/prune-e2e-verification-evidence.sh --dry-run` lists candidates). Routing truth is **not** inferred from old reports—use [ALL_VMIDS_ENDPOINTS.md](ALL_VMIDS_ENDPOINTS.md).
|
||||
@@ -41,7 +42,7 @@
|
||||
| studio.sankofa.nexus | web | https://studio.sankofa.nexus | Sankofa Studio (FusionAI Creator) at VMID 7805. |
|
||||
| keycloak.sankofa.nexus | web | https://keycloak.sankofa.nexus | Keycloak IdP (VMID 7802); client SSO for admin/portal. |
|
||||
| admin.sankofa.nexus | web | https://admin.sankofa.nexus | Client SSO: access administration (hostname intent; NPM upstream TBD). |
|
||||
| portal.sankofa.nexus | web | https://portal.sankofa.nexus | Client SSO: portal / marketplace (typical upstream VMID 7801). |
|
||||
| portal.sankofa.nexus | web | https://portal.sankofa.nexus | Client SSO: portal / marketplace (typical upstream VMID 7801). Add DNS + NPM row via `update-npmplus-proxy-hosts-api.sh`; NextAuth public URL `https://portal.sankofa.nexus`. |
|
||||
| dash.sankofa.nexus | web | https://dash.sankofa.nexus | Operator systems dashboard (IP allowlist + MFA intent; upstream TBD). |
|
||||
| docs.d-bis.org | web | https://docs.d-bis.org | Docs on explorer nginx where configured. |
|
||||
| blockscout.defi-oracle.io | web | https://blockscout.defi-oracle.io | Generic Blockscout hostname (often VMID 5000); not canonical Chain 138 **explorer.d-bis.org**. |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# FQDN expected content (what users and clients should see)
|
||||
|
||||
**Last Updated:** 2026-03-27 (aligned with EXPECTED_WEB_CONTENT deployment table v1.5)
|
||||
**Last Updated:** 2026-03-29 (NPM fleet script includes `portal` / `admin` / optional `dash`; apex uses `IP_SANKOFA_PUBLIC_WEB`)
|
||||
**Purpose:** One-page description of **what should be presented** at each public NPM-routed hostname after HTTPS. Use this before pruning evidence or changing proxies so expectations stay aligned with product intent.
|
||||
|
||||
**Canonical routing (IPs, VMIDs, ports):** [ALL_VMIDS_ENDPOINTS.md](ALL_VMIDS_ENDPOINTS.md), [RPC_ENDPOINTS_MASTER.md](RPC_ENDPOINTS_MASTER.md).
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
| FQDN | Kind | What should be displayed or returned |
|
||||
|------|------|--------------------------------------|
|
||||
| `sankofa.nexus` | Web | **Sankofa — Sovereign Technologies:** public corporate / brand web (mission, narrative, entry points). |
|
||||
| `sankofa.nexus` | Web | **Sankofa — Sovereign Technologies:** public corporate / brand web (mission, narrative, entry points). NPM upstream: **`IP_SANKOFA_PUBLIC_WEB`:`SANKOFA_PUBLIC_WEB_PORT`** (defaults to portal IP until marketing CT is split). |
|
||||
| `www.sankofa.nexus` | 301 → apex | Browser ends on `https://sankofa.nexus/...`. |
|
||||
| `phoenix.sankofa.nexus` | Web / API | **Phoenix Cloud Services** (division of Sankofa): public-facing **division web** (intent). Same deployment may still expose API paths (`/health`, `/graphql`, …). E2E verifier may use `/health`. |
|
||||
| `www.phoenix.sankofa.nexus` | 301 → apex | Browser ends on `https://phoenix.sankofa.nexus/...`. |
|
||||
@@ -48,8 +48,8 @@
|
||||
| FQDN | VMID / target | Notes |
|
||||
|------|---------------|--------|
|
||||
| `keycloak.sankofa.nexus` | **7802** (detail in [ALL_VMIDS_ENDPOINTS.md](ALL_VMIDS_ENDPOINTS.md)) | IdP + `/admin` for platform operators |
|
||||
| `portal.sankofa.nexus` | **7801** · `192.168.11.51:3000` | ✅ **Active** when NPM routes here; public OIDC / `NEXTAUTH_URL` via `scripts/deployment/sync-sankofa-portal-7801.sh` |
|
||||
| `admin.sankofa.nexus` | 🔶 **Not pinned** in VM inventory | Hostname **intent**; NPM + app upstream TBD; may share **7801** until split |
|
||||
| `portal.sankofa.nexus` | **`IP_SANKOFA_CLIENT_SSO`** (typ. **7801** · `192.168.11.51:3000`) | Fleet script creates/updates NPM row; default **`NEXTAUTH_URL=https://portal.sankofa.nexus`** (`sync-sankofa-portal-7801.sh`) |
|
||||
| `admin.sankofa.nexus` | same as **`IP_SANKOFA_CLIENT_SSO`** | Shares portal upstream until split; NPM row in fleet script |
|
||||
|
||||
### Operator / systems (IP-gated + MFA)
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
|
||||
## Operator checklist
|
||||
|
||||
- **Wrong content** (e.g. explorer UI on `sankofa.nexus`, or HTML on RPC hostname) usually means **NPM upstream** or **DNS** is wrong — fix with `update-npmplus-proxy-hosts-api.sh` and [ALL_VMIDS_ENDPOINTS.md](ALL_VMIDS_ENDPOINTS.md).
|
||||
- **Wrong content** (e.g. explorer UI on `sankofa.nexus`, or HTML on RPC hostname) usually means **NPM upstream** or **DNS** is wrong — fix with `update-npmplus-proxy-hosts-api.sh` and [ALL_VMIDS_ENDPOINTS.md](ALL_VMIDS_ENDPOINTS.md). Ensure **`portal.sankofa.nexus`** / **`admin.sankofa.nexus`** DNS exist; **`dash`** is created in NPM only when **`IP_SANKOFA_DASH`** is set in `config/ip-addresses.conf`.
|
||||
- **301 on `www.*`** is intentional; content is judged on the **apex** hostname after redirect.
|
||||
|
||||
---
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
| Contract / address status | [11-references/ADDRESS_MATRIX_AND_STATUS.md](11-references/ADDRESS_MATRIX_AND_STATUS.md), [11-references/CONTRACT_ADDRESSES_REFERENCE.md](11-references/CONTRACT_ADDRESSES_REFERENCE.md), [11-references/CONTRACT_NEXT_STEPS_LIST.md](11-references/CONTRACT_NEXT_STEPS_LIST.md) (59-addr check) | CONTRACT_INVENTORY_AND_VERIFICATION (deleted) |
|
||||
| **Proxmox VMIDs, LAN IPs, NPM targets** | [04-configuration/ALL_VMIDS_ENDPOINTS.md](04-configuration/ALL_VMIDS_ENDPOINTS.md), [`config/ip-addresses.conf`](../config/ip-addresses.conf), [11-references/NETWORK_CONFIGURATION_MASTER.md](11-references/NETWORK_CONFIGURATION_MASTER.md), [`config/proxmox-operational-template.json`](../config/proxmox-operational-template.json) | Dated inventories under `docs/archive/` (paths on disk only) |
|
||||
| **FQDN → expected content (web / API / RPC)** | [04-configuration/FQDN_EXPECTED_CONTENT.md](04-configuration/FQDN_EXPECTED_CONTENT.md) | — |
|
||||
| **Sankofa / Phoenix public vs portal vs admin endpoints (fix list)** | [03-deployment/SANKOFA_PHOENIX_PUBLIC_PORTAL_ADMIN_ENDPOINT_CORRECTION_TASKS.md](03-deployment/SANKOFA_PHOENIX_PUBLIC_PORTAL_ADMIN_ENDPOINT_CORRECTION_TASKS.md) | — |
|
||||
| **IP conflict resolutions** | [reports/status/IP_CONFLICTS_RESOLUTION_COMPLETE.md](../reports/status/IP_CONFLICTS_RESOLUTION_COMPLETE.md), `scripts/resolve-ip-conflicts.sh` | — |
|
||||
|
||||
---
|
||||
@@ -58,7 +59,7 @@
|
||||
|------|-----------------|
|
||||
| **00-meta** (tasks, next steps, phases) | [00-meta/NEXT_STEPS_INDEX.md](00-meta/NEXT_STEPS_INDEX.md), [00-meta/PHASES_AND_TASKS_MASTER.md](00-meta/PHASES_AND_TASKS_MASTER.md) |
|
||||
| **02-architecture** | [02-architecture/](02-architecture/) — **Public sector + Phoenix catalog baseline:** [02-architecture/PUBLIC_SECTOR_TENANCY_MARKETPLACE_AND_DEPLOYMENT_BASELINE.md](02-architecture/PUBLIC_SECTOR_TENANCY_MARKETPLACE_AND_DEPLOYMENT_BASELINE.md); **non-goals (incl. catalog vs marketing §9):** [02-architecture/NON_GOALS.md](02-architecture/NON_GOALS.md); **DBIS Chain 138:** [dbis_chain_138_technical_master_plan.md](../dbis_chain_138_technical_master_plan.md), [02-architecture/DBIS_NODE_ROLE_MATRIX.md](02-architecture/DBIS_NODE_ROLE_MATRIX.md), [02-architecture/DBIS_PHASE2_PROXMOX_SOVEREIGNIZATION_ROADMAP.md](02-architecture/DBIS_PHASE2_PROXMOX_SOVEREIGNIZATION_ROADMAP.md) |
|
||||
| **03-deployment** | [03-deployment/OPERATIONAL_RUNBOOKS.md](03-deployment/OPERATIONAL_RUNBOOKS.md), [03-deployment/DEPLOYMENT_ORDER_OF_OPERATIONS.md](03-deployment/DEPLOYMENT_ORDER_OF_OPERATIONS.md), **Public sector live checklist:** [03-deployment/PUBLIC_SECTOR_LIVE_DEPLOYMENT_CHECKLIST.md](03-deployment/PUBLIC_SECTOR_LIVE_DEPLOYMENT_CHECKLIST.md), **Proxmox VE ops template:** [03-deployment/PROXMOX_VE_OPERATIONAL_DEPLOYMENT_TEMPLATE.md](03-deployment/PROXMOX_VE_OPERATIONAL_DEPLOYMENT_TEMPLATE.md) · [`config/proxmox-operational-template.json`](config/proxmox-operational-template.json); **DBIS Phase 1–3:** [03-deployment/PHASE1_DISCOVERY_RUNBOOK.md](03-deployment/PHASE1_DISCOVERY_RUNBOOK.md), [03-deployment/DBIS_PHASE3_E2E_PRODUCTION_SIMULATION_RUNBOOK.md](03-deployment/DBIS_PHASE3_E2E_PRODUCTION_SIMULATION_RUNBOOK.md), [03-deployment/CALIPER_CHAIN138_PERF_HOOK.md](03-deployment/CALIPER_CHAIN138_PERF_HOOK.md), [03-deployment/DBIS_HYPERLEDGER_RUNTIME_STATUS.md](03-deployment/DBIS_HYPERLEDGER_RUNTIME_STATUS.md), [03-deployment/DBIS_PHASES_1_TO_3_PRODUCTION_GATE.md](03-deployment/DBIS_PHASES_1_TO_3_PRODUCTION_GATE.md), **RTGS canonical production checklist and institutional-finance layers:** [03-deployment/DBIS_RTGS_E2E_REQUIREMENTS_MATRIX.md](03-deployment/DBIS_RTGS_E2E_REQUIREMENTS_MATRIX.md), [03-deployment/DBIS_RTGS_FX_TRANSACTION_CATALOG.md](03-deployment/DBIS_RTGS_FX_TRANSACTION_CATALOG.md), [03-deployment/DBIS_RTGS_DEPOSITORY_AND_CUSTODY_OPERATING_MODEL.md](03-deployment/DBIS_RTGS_DEPOSITORY_AND_CUSTODY_OPERATING_MODEL.md), [03-deployment/DBIS_RTGS_FX_AND_LIQUIDITY_OPERATING_MODEL.md](03-deployment/DBIS_RTGS_FX_AND_LIQUIDITY_OPERATING_MODEL.md), [03-deployment/DBIS_RTGS_CONTROL_PLANE_DEPLOYMENT_CHECKLIST.md](03-deployment/DBIS_RTGS_CONTROL_PLANE_DEPLOYMENT_CHECKLIST.md), [03-deployment/DBIS_RTGS_LATER_PHASE_SIDECARS_DEPLOYMENT_CHECKLIST.md](03-deployment/DBIS_RTGS_LATER_PHASE_SIDECARS_DEPLOYMENT_CHECKLIST.md), [03-deployment/DBIS_OMNL_INDONESIA_BNI_E2E_INTEGRATION_BLUEPRINT.md](03-deployment/DBIS_OMNL_INDONESIA_BNI_E2E_INTEGRATION_BLUEPRINT.md), [03-deployment/DBIS_RTGS_FIRST_SLICE_ARCHITECTURE.md](03-deployment/DBIS_RTGS_FIRST_SLICE_ARCHITECTURE.md), [03-deployment/DBIS_RTGS_FIRST_SLICE_DEPLOYMENT_CHECKLIST.md](03-deployment/DBIS_RTGS_FIRST_SLICE_DEPLOYMENT_CHECKLIST.md), [03-deployment/DBIS_HYBX_SIDECAR_BOUNDARY_MATRIX.md](03-deployment/DBIS_HYBX_SIDECAR_BOUNDARY_MATRIX.md), [03-deployment/DBIS_MOJALOOP_INTEGRATION_STATUS.md](03-deployment/DBIS_MOJALOOP_INTEGRATION_STATUS.md), [03-deployment/DBIS_HYPERLEDGER_IDENTITY_STACK_DECISION.md](03-deployment/DBIS_HYPERLEDGER_IDENTITY_STACK_DECISION.md) |
|
||||
| **03-deployment** | [03-deployment/OPERATIONAL_RUNBOOKS.md](03-deployment/OPERATIONAL_RUNBOOKS.md), [03-deployment/DEPLOYMENT_ORDER_OF_OPERATIONS.md](03-deployment/DEPLOYMENT_ORDER_OF_OPERATIONS.md), **Public sector live checklist:** [03-deployment/PUBLIC_SECTOR_LIVE_DEPLOYMENT_CHECKLIST.md](03-deployment/PUBLIC_SECTOR_LIVE_DEPLOYMENT_CHECKLIST.md), **Proxmox VE ops template:** [03-deployment/PROXMOX_VE_OPERATIONAL_DEPLOYMENT_TEMPLATE.md](03-deployment/PROXMOX_VE_OPERATIONAL_DEPLOYMENT_TEMPLATE.md) · [`config/proxmox-operational-template.json`](config/proxmox-operational-template.json); **DBIS Phase 1–3:** [03-deployment/PHASE1_DISCOVERY_RUNBOOK.md](03-deployment/PHASE1_DISCOVERY_RUNBOOK.md), [03-deployment/DBIS_PHASE3_E2E_PRODUCTION_SIMULATION_RUNBOOK.md](03-deployment/DBIS_PHASE3_E2E_PRODUCTION_SIMULATION_RUNBOOK.md), [03-deployment/CALIPER_CHAIN138_PERF_HOOK.md](03-deployment/CALIPER_CHAIN138_PERF_HOOK.md), [03-deployment/DBIS_HYPERLEDGER_RUNTIME_STATUS.md](03-deployment/DBIS_HYPERLEDGER_RUNTIME_STATUS.md), [03-deployment/DBIS_PHASES_1_TO_3_PRODUCTION_GATE.md](03-deployment/DBIS_PHASES_1_TO_3_PRODUCTION_GATE.md), **RTGS canonical production checklist and institutional-finance layers:** [03-deployment/DBIS_RTGS_E2E_REQUIREMENTS_MATRIX.md](03-deployment/DBIS_RTGS_E2E_REQUIREMENTS_MATRIX.md), [03-deployment/DBIS_RTGS_FX_TRANSACTION_CATALOG.md](03-deployment/DBIS_RTGS_FX_TRANSACTION_CATALOG.md), [03-deployment/DBIS_RTGS_DEPOSITORY_AND_CUSTODY_OPERATING_MODEL.md](03-deployment/DBIS_RTGS_DEPOSITORY_AND_CUSTODY_OPERATING_MODEL.md), [03-deployment/DBIS_RTGS_FX_AND_LIQUIDITY_OPERATING_MODEL.md](03-deployment/DBIS_RTGS_FX_AND_LIQUIDITY_OPERATING_MODEL.md), [03-deployment/DBIS_RTGS_CONTROL_PLANE_DEPLOYMENT_CHECKLIST.md](03-deployment/DBIS_RTGS_CONTROL_PLANE_DEPLOYMENT_CHECKLIST.md), [03-deployment/DBIS_RTGS_LATER_PHASE_SIDECARS_DEPLOYMENT_CHECKLIST.md](03-deployment/DBIS_RTGS_LATER_PHASE_SIDECARS_DEPLOYMENT_CHECKLIST.md), [03-deployment/DBIS_OMNL_INDONESIA_BNI_E2E_INTEGRATION_BLUEPRINT.md](03-deployment/DBIS_OMNL_INDONESIA_BNI_E2E_INTEGRATION_BLUEPRINT.md), [03-deployment/DBIS_OMNL_INDONESIA_BNI_E2E_EXECUTABLE_TASK_LIST.md](03-deployment/DBIS_OMNL_INDONESIA_BNI_E2E_EXECUTABLE_TASK_LIST.md), [03-deployment/DBIS_OMNL_INDONESIA_BNI_E2E_EXECUTION_STATUS_2026-03-29.md](03-deployment/DBIS_OMNL_INDONESIA_BNI_E2E_EXECUTION_STATUS_2026-03-29.md), [03-deployment/DBIS_RTGS_FIRST_SLICE_ARCHITECTURE.md](03-deployment/DBIS_RTGS_FIRST_SLICE_ARCHITECTURE.md), [03-deployment/DBIS_RTGS_FIRST_SLICE_DEPLOYMENT_CHECKLIST.md](03-deployment/DBIS_RTGS_FIRST_SLICE_DEPLOYMENT_CHECKLIST.md), [03-deployment/DBIS_HYBX_SIDECAR_BOUNDARY_MATRIX.md](03-deployment/DBIS_HYBX_SIDECAR_BOUNDARY_MATRIX.md), [03-deployment/DBIS_MOJALOOP_INTEGRATION_STATUS.md](03-deployment/DBIS_MOJALOOP_INTEGRATION_STATUS.md), [03-deployment/DBIS_HYPERLEDGER_IDENTITY_STACK_DECISION.md](03-deployment/DBIS_HYPERLEDGER_IDENTITY_STACK_DECISION.md), [03-deployment/DBIS_IDENTITY_COMPLETION_PACKAGE_RUNBOOK.md](03-deployment/DBIS_IDENTITY_COMPLETION_PACKAGE_RUNBOOK.md) |
|
||||
| **04-configuration** | [04-configuration/README.md](04-configuration/README.md), [04-configuration/ADDITIONAL_PATHS_AND_EXTENSIONS.md](04-configuration/ADDITIONAL_PATHS_AND_EXTENSIONS.md) (paths, registry, token-mapping, LiFi/Jumper); **Chain 138 wallets:** [04-configuration/CHAIN138_WALLET_CONFIG_VALIDATION.md](04-configuration/CHAIN138_WALLET_CONFIG_VALIDATION.md); **Chain 2138 testnet wallets:** [04-configuration/CHAIN2138_WALLET_CONFIG_VALIDATION.md](04-configuration/CHAIN2138_WALLET_CONFIG_VALIDATION.md); **OMNL Indonesia / HYBX-BATCH-001:** [04-configuration/mifos-omnl-central-bank/HYBX_BATCH_001_OPERATOR_CHECKLIST.md](04-configuration/mifos-omnl-central-bank/HYBX_BATCH_001_OPERATOR_CHECKLIST.md), [04-configuration/mifos-omnl-central-bank/INDONESIA_PACKAGE_4_995_EVIDENCE_STANDARD.md](04-configuration/mifos-omnl-central-bank/INDONESIA_PACKAGE_4_995_EVIDENCE_STANDARD.md) |
|
||||
| **06-besu** | [06-besu/MASTER_INDEX.md](06-besu/MASTER_INDEX.md) |
|
||||
| **Testnet (2138)** | [testnet/DEFI_ORACLE_META_TESTNET_2138_RUNBOOK.md](testnet/DEFI_ORACLE_META_TESTNET_2138_RUNBOOK.md), [testnet/TESTNET_DEPLOYMENT.md](testnet/TESTNET_DEPLOYMENT.md) |
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# Enable working login on https://sankofa.nexus:
|
||||
# Enable working login on the client portal hostname (https://portal.sankofa.nexus; NEXTAUTH_URL):
|
||||
# - Fix Keycloak systemd (JAVA_HOME line; hostname + proxy headers for NPM).
|
||||
# - Remove .env.local on CT 7801; install .env with PORTAL_LOCAL_LOGIN_* + NEXTAUTH_SECRET.
|
||||
# - Run sync-sankofa-portal-7801.sh (rebuild portal with updated auth.ts).
|
||||
@@ -32,7 +32,7 @@ cat > "$ENV_TMP" <<EOF
|
||||
NEXT_PUBLIC_GRAPHQL_ENDPOINT=http://192.168.11.50:4000/graphql
|
||||
NEXT_PUBLIC_GRAPHQL_WS_ENDPOINT=ws://192.168.11.50:4000/graphql-ws
|
||||
|
||||
NEXTAUTH_URL=https://sankofa.nexus
|
||||
NEXTAUTH_URL=https://portal.sankofa.nexus
|
||||
NEXTAUTH_SECRET=${NEXTAUTH_SEC}
|
||||
KEYCLOAK_URL=https://keycloak.sankofa.nexus
|
||||
KEYCLOAK_REALM=master
|
||||
@@ -85,7 +85,7 @@ bash "${SCRIPT_DIR}/sync-sankofa-portal-7801.sh"
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo "✅ Sign in at https://sankofa.nexus"
|
||||
echo "✅ Sign in at https://portal.sankofa.nexus (NEXTAUTH_URL)"
|
||||
echo " Email: ${LOCAL_EMAIL}"
|
||||
echo " Password: ${GEN_PASS}"
|
||||
echo ""
|
||||
|
||||
101
scripts/deployment/keycloak-sankofa-ensure-client-redirects.sh
Executable file
101
scripts/deployment/keycloak-sankofa-ensure-client-redirects.sh
Executable file
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/env bash
|
||||
# Ensure Keycloak OIDC client has redirect URIs and web origins for portal/admin hostnames.
|
||||
# Uses Admin REST API (password grant on master realm). Set secrets in .env (not committed).
|
||||
#
|
||||
# Required env: KEYCLOAK_ADMIN_PASSWORD
|
||||
# Optional: KEYCLOAK_URL (default https://keycloak.sankofa.nexus), KEYCLOAK_ADMIN (default admin),
|
||||
# KEYCLOAK_REALM (default master), KEYCLOAK_CLIENT_ID (default sankofa-portal)
|
||||
#
|
||||
# Usage: from repo root with .env loaded:
|
||||
# ./scripts/deployment/keycloak-sankofa-ensure-client-redirects.sh
|
||||
# ./scripts/deployment/keycloak-sankofa-ensure-client-redirects.sh --dry-run
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
if [ -f "$PROJECT_ROOT/.env" ]; then
|
||||
set +u
|
||||
set -a
|
||||
# shellcheck source=/dev/null
|
||||
source "$PROJECT_ROOT/.env" 2>/dev/null || true
|
||||
set +a
|
||||
set -u
|
||||
fi
|
||||
|
||||
KEYCLOAK_URL="${KEYCLOAK_URL:-https://keycloak.sankofa.nexus}"
|
||||
REALM="${KEYCLOAK_REALM:-master}"
|
||||
CLIENT_ID="${KEYCLOAK_CLIENT_ID:-sankofa-portal}"
|
||||
ADMIN_USER="${KEYCLOAK_ADMIN:-admin}"
|
||||
ADMIN_PASS="${KEYCLOAK_ADMIN_PASSWORD:-}"
|
||||
|
||||
DRY=0
|
||||
[[ "${1:-}" == "--dry-run" ]] && DRY=1
|
||||
|
||||
if [ -z "$ADMIN_PASS" ]; then
|
||||
echo "KEYCLOAK_ADMIN_PASSWORD is not set. Add it to .env (or export) and re-run." >&2
|
||||
echo "Without it, update the client manually: Valid redirect URIs + Web origins for portal/admin." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TOKEN_JSON=$(curl -sS -X POST "${KEYCLOAK_URL}/realms/master/protocol/openid-connect/token" \
|
||||
-d "grant_type=password" \
|
||||
-d "client_id=admin-cli" \
|
||||
-d "username=${ADMIN_USER}" \
|
||||
-d "password=${ADMIN_PASS}")
|
||||
|
||||
TOKEN=$(echo "$TOKEN_JSON" | jq -r '.access_token // empty')
|
||||
if [ -z "$TOKEN" ] || [ "$TOKEN" = "null" ]; then
|
||||
echo "Failed to obtain admin token (check URL, user, password)." >&2
|
||||
echo "$TOKEN_JSON" | jq -r '.error_description // .error // .' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CLIENT_LIST=$(curl -sS -G "${KEYCLOAK_URL}/admin/realms/${REALM}/clients" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
--data-urlencode "clientId=${CLIENT_ID}")
|
||||
|
||||
INTERNAL_ID=$(echo "$CLIENT_LIST" | jq -r '.[0].id // empty')
|
||||
if [ -z "$INTERNAL_ID" ] || [ "$INTERNAL_ID" = "null" ]; then
|
||||
echo "No client with clientId=${CLIENT_ID} in realm ${REALM}." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
FULL=$(curl -sS "${KEYCLOAK_URL}/admin/realms/${REALM}/clients/${INTERNAL_ID}" \
|
||||
-H "Authorization: Bearer ${TOKEN}")
|
||||
|
||||
DESIRED_REDIRECTS='[
|
||||
"https://portal.sankofa.nexus/*",
|
||||
"https://portal.sankofa.nexus",
|
||||
"https://admin.sankofa.nexus/*",
|
||||
"https://admin.sankofa.nexus"
|
||||
]'
|
||||
DESIRED_ORIGINS='[
|
||||
"https://portal.sankofa.nexus",
|
||||
"https://admin.sankofa.nexus"
|
||||
]'
|
||||
|
||||
MERGED=$(echo "$FULL" | jq --argjson dr "$DESIRED_REDIRECTS" --argjson wo "$DESIRED_ORIGINS" '
|
||||
.redirectUris = ((.redirectUris // []) + $dr | unique) |
|
||||
.webOrigins = ((.webOrigins // []) + $wo | unique)
|
||||
')
|
||||
|
||||
if [ "$DRY" = 1 ]; then
|
||||
echo "[dry-run] Would set client ${CLIENT_ID} (${INTERNAL_ID}) to:"
|
||||
echo "$MERGED" | jq '{clientId, redirectUris, webOrigins}'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
HTTP_CODE=$(curl -sS -o /tmp/kc_put_body.txt -w "%{http_code}" -X PUT \
|
||||
"${KEYCLOAK_URL}/admin/realms/${REALM}/clients/${INTERNAL_ID}" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$MERGED")
|
||||
|
||||
if [[ "$HTTP_CODE" != "204" && "$HTTP_CODE" != "200" ]]; then
|
||||
echo "PUT client failed HTTP ${HTTP_CODE}" >&2
|
||||
cat /tmp/kc_put_body.txt >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -f /tmp/kc_put_body.txt
|
||||
echo "Updated Keycloak client ${CLIENT_ID}: redirect URIs and web origins merged (portal + admin)."
|
||||
89
scripts/deployment/provision-sankofa-public-web-lxc-7806.sh
Executable file
89
scripts/deployment/provision-sankofa-public-web-lxc-7806.sh
Executable file
@@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env bash
|
||||
# Create LXC 7806 (sankofa-public-web) for corporate Next.js at repo root → sankofa.nexus via IP_SANKOFA_PUBLIC_WEB.
|
||||
# Installs Node 20 + pnpm and systemd unit; then run sync-sankofa-public-web-to-ct.sh and NPM fleet update.
|
||||
#
|
||||
# Usage (from repo root, SSH to r630-01):
|
||||
# bash scripts/deployment/provision-sankofa-public-web-lxc-7806.sh [--dry-run]
|
||||
#
|
||||
# Env: PROXMOX_HOST, SANKOFA_PUBLIC_WEB_VMID (7806), IP_SANKOFA_PUBLIC_WEB_CT (default 192.168.11.63)
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
# shellcheck source=/dev/null
|
||||
source "${PROJECT_ROOT}/config/ip-addresses.conf" 2>/dev/null || true
|
||||
|
||||
PROXMOX_HOST="${PROXMOX_HOST:-${PROXMOX_HOST_R630_01:-192.168.11.11}}"
|
||||
VMID="${SANKOFA_PUBLIC_WEB_VMID:-7806}"
|
||||
IP_CT="${IP_SANKOFA_PUBLIC_WEB_CT:-192.168.11.63}"
|
||||
HOSTNAME_CT="${SANKOFA_PUBLIC_WEB_HOSTNAME:-sankofa-public-web}"
|
||||
TEMPLATE="${TEMPLATE:-local:vztmpl/debian-12-standard_12.12-1_amd64.tar.zst}"
|
||||
STORAGE="${STORAGE:-local-lvm}"
|
||||
NETWORK="${NETWORK:-vmbr0}"
|
||||
GATEWAY="${NETWORK_GATEWAY:-192.168.11.1}"
|
||||
SSH_OPTS="-o BatchMode=yes -o ConnectTimeout=15 -o StrictHostKeyChecking=accept-new"
|
||||
SERVICE_FILE="${PROJECT_ROOT}/config/systemd/sankofa-public-web.service"
|
||||
|
||||
DRY_RUN=false
|
||||
[[ "${1:-}" == "--dry-run" ]] && DRY_RUN=true
|
||||
|
||||
echo "=== Provision Sankofa public web LXC ${VMID} (${IP_CT}) ==="
|
||||
echo "Proxmox: ${PROXMOX_HOST}"
|
||||
|
||||
if [[ ! -f "$SERVICE_FILE" ]]; then
|
||||
echo "ERROR: Missing $SERVICE_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if $DRY_RUN; then
|
||||
echo "[DRY-RUN] Would create CT ${VMID} if missing, install Node/pnpm, install systemd unit"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ssh $SSH_OPTS "root@${PROXMOX_HOST}" "pct list 2>/dev/null | grep -q '^${VMID} '"; then
|
||||
echo "CT ${VMID} already exists — skipping pct create"
|
||||
else
|
||||
echo "Creating CT ${VMID} (${HOSTNAME_CT}) @ ${IP_CT}/24..."
|
||||
ssh $SSH_OPTS "root@${PROXMOX_HOST}" bash -s <<EOF
|
||||
set -euo pipefail
|
||||
pct create ${VMID} ${TEMPLATE} \
|
||||
--hostname ${HOSTNAME_CT} \
|
||||
--memory 6144 \
|
||||
--cores 2 \
|
||||
--rootfs ${STORAGE}:32 \
|
||||
--net0 name=eth0,bridge=${NETWORK},ip=${IP_CT}/24,gw=${GATEWAY} \
|
||||
--nameserver ${DNS_PRIMARY:-1.1.1.1} \
|
||||
--description 'Sankofa corporate public web (Next.js root) — sankofa.nexus via NPM IP_SANKOFA_PUBLIC_WEB' \
|
||||
--start 1 \
|
||||
--onboot 1 \
|
||||
--unprivileged 0
|
||||
EOF
|
||||
echo "Waiting for CT to boot..."
|
||||
sleep 20
|
||||
fi
|
||||
|
||||
ssh $SSH_OPTS "root@${PROXMOX_HOST}" "pct status ${VMID}" | grep -q running || { echo "ERROR: CT ${VMID} not running"; exit 1; }
|
||||
|
||||
echo "Installing Node 20 + pnpm inside CT ${VMID}..."
|
||||
ssh $SSH_OPTS "root@${PROXMOX_HOST}" "pct exec ${VMID} -- bash -lc '
|
||||
set -euo pipefail
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq ca-certificates curl gnupg
|
||||
if ! command -v node >/dev/null 2>&1 || ! node -v | grep -q \"^v20\"; then
|
||||
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
|
||||
apt-get install -y -qq nodejs
|
||||
fi
|
||||
command -v pnpm >/dev/null 2>&1 || npm install -g pnpm
|
||||
mkdir -p /opt/sankofa-public-web
|
||||
'"
|
||||
|
||||
echo "Installing systemd unit..."
|
||||
scp $SSH_OPTS "$SERVICE_FILE" "root@${PROXMOX_HOST}:/tmp/sankofa-public-web.service"
|
||||
ssh $SSH_OPTS "root@${PROXMOX_HOST}" "pct push ${VMID} /tmp/sankofa-public-web.service /etc/systemd/system/sankofa-public-web.service && rm -f /tmp/sankofa-public-web.service"
|
||||
ssh $SSH_OPTS "root@${PROXMOX_HOST}" "pct exec ${VMID} -- systemctl daemon-reload"
|
||||
ssh $SSH_OPTS "root@${PROXMOX_HOST}" "pct exec ${VMID} -- systemctl enable sankofa-public-web"
|
||||
|
||||
echo "✅ CT ${VMID} ready. Next:"
|
||||
echo " SANKOFA_PUBLIC_WEB_VMID=${VMID} bash scripts/deployment/sync-sankofa-public-web-to-ct.sh"
|
||||
echo " Then set IP_SANKOFA_PUBLIC_WEB=${IP_CT} and run scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh"
|
||||
@@ -14,7 +14,7 @@ PROXMOX_HOST="${PROXMOX_HOST:-${PROXMOX_HOST_R630_01:-192.168.11.11}}"
|
||||
VMID="${SANKOFA_PORTAL_VMID:-7801}"
|
||||
CT_APP_DIR="${SANKOFA_PORTAL_CT_DIR:-/opt/sankofa-portal}"
|
||||
SERVICE_NAME="${SANKOFA_PORTAL_SERVICE:-sankofa-portal}"
|
||||
NEXTAUTH_PUBLIC_URL="${SANKOFA_PORTAL_NEXTAUTH_URL:-https://sankofa.nexus}"
|
||||
NEXTAUTH_PUBLIC_URL="${SANKOFA_PORTAL_NEXTAUTH_URL:-https://portal.sankofa.nexus}"
|
||||
SSH_OPTS="-o BatchMode=yes -o ConnectTimeout=15 -o StrictHostKeyChecking=accept-new"
|
||||
|
||||
ssh $SSH_OPTS "root@${PROXMOX_HOST}" "pct exec ${VMID} -- bash -s" <<EOF
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# ./scripts/deployment/sync-sankofa-portal-7801.sh [--dry-run]
|
||||
# Env:
|
||||
# PROXMOX_HOST (default 192.168.11.11), SANKOFA_PORTAL_VMID (7801), SANKOFA_PORTAL_SRC, IP_SANKOFA_PORTAL (for post-check only)
|
||||
# SANKOFA_PORTAL_NEXTAUTH_URL (default https://sankofa.nexus) — applied on CT after build
|
||||
# SANKOFA_PORTAL_NEXTAUTH_URL (default https://portal.sankofa.nexus) — applied on CT after build
|
||||
#
|
||||
# See: docs/03-deployment/PUBLIC_SECTOR_LIVE_DEPLOYMENT_CHECKLIST.md (Phoenix CT 7801)
|
||||
|
||||
@@ -97,14 +97,14 @@ REMOTE_EOF
|
||||
|
||||
echo ""
|
||||
echo "🔐 Ensuring NextAuth URL/secret on CT (see sankofa-portal-ensure-nextauth-on-ct.sh)…"
|
||||
SANKOFA_PORTAL_NEXTAUTH_URL="${SANKOFA_PORTAL_NEXTAUTH_URL:-https://sankofa.nexus}"
|
||||
SANKOFA_PORTAL_NEXTAUTH_URL="${SANKOFA_PORTAL_NEXTAUTH_URL:-https://portal.sankofa.nexus}"
|
||||
export SANKOFA_PORTAL_VMID SANKOFA_PORTAL_CT_DIR SANKOFA_PORTAL_SERVICE SANKOFA_PORTAL_NEXTAUTH_URL PROXMOX_HOST
|
||||
bash "${SCRIPT_DIR}/sankofa-portal-ensure-nextauth-on-ct.sh"
|
||||
|
||||
echo ""
|
||||
echo "✅ Done. Verify:"
|
||||
echo " curl -sS http://${IP_SANKOFA_PORTAL:-192.168.11.51}:3000/ | head -c 120"
|
||||
echo " curl -sSI https://sankofa.nexus/api/auth/signin | head -n 15"
|
||||
echo " https://sankofa.nexus/ (via NPM)"
|
||||
echo " curl -sSI https://portal.sankofa.nexus/api/auth/signin | head -n 15"
|
||||
echo " https://portal.sankofa.nexus/ (via NPM; corporate apex is sankofa.nexus → IP_SANKOFA_PUBLIC_WEB)"
|
||||
echo ""
|
||||
echo "Override public auth URL: SANKOFA_PORTAL_NEXTAUTH_URL=https://portal.sankofa.nexus $0"
|
||||
echo "Legacy apex auth URL only if needed: SANKOFA_PORTAL_NEXTAUTH_URL=https://sankofa.nexus $0"
|
||||
|
||||
106
scripts/deployment/sync-sankofa-public-web-to-ct.sh
Executable file
106
scripts/deployment/sync-sankofa-public-web-to-ct.sh
Executable file
@@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env bash
|
||||
# Sync Sankofa repo-root Next.js app (corporate / marketing site) to a dedicated LXC for apex sankofa.nexus.
|
||||
# Does not run NextAuth portal setup — use sync-sankofa-portal-7801.sh for client SSO on portal.sankofa.nexus.
|
||||
#
|
||||
# Prerequisites: SSH root@PROXMOX_HOST; sibling repo at ../Sankofa (root package.json + src/app + public/).
|
||||
# On the CT: install systemd unit config/systemd/sankofa-public-web.service → /etc/systemd/system/ and enable.
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/deployment/sync-sankofa-public-web-to-ct.sh [--dry-run]
|
||||
# Env:
|
||||
# PROXMOX_HOST, SANKOFA_PUBLIC_WEB_VMID (default 7806), SANKOFA_PUBLIC_WEB_SRC, SANKOFA_PUBLIC_WEB_CT_DIR, SANKOFA_PUBLIC_WEB_SERVICE
|
||||
#
|
||||
# After first deploy: set IP_SANKOFA_PUBLIC_WEB + SANKOFA_PUBLIC_WEB_PORT in config/ip-addresses.conf (or .env) and run
|
||||
# scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
# shellcheck source=/dev/null
|
||||
source "${PROJECT_ROOT}/config/ip-addresses.conf" 2>/dev/null || true
|
||||
|
||||
PROXMOX_HOST="${PROXMOX_HOST:-${PROXMOX_HOST_R630_01:-192.168.11.11}}"
|
||||
VMID="${SANKOFA_PUBLIC_WEB_VMID:-7806}"
|
||||
CT_APP_DIR="${SANKOFA_PUBLIC_WEB_CT_DIR:-/opt/sankofa-public-web}"
|
||||
SERVICE_NAME="${SANKOFA_PUBLIC_WEB_SERVICE:-sankofa-public-web}"
|
||||
SSH_OPTS="-o BatchMode=yes -o ConnectTimeout=15 -o StrictHostKeyChecking=accept-new"
|
||||
|
||||
DEFAULT_SRC="${PROJECT_ROOT}/../Sankofa"
|
||||
if [[ -d "$DEFAULT_SRC" && -f "$DEFAULT_SRC/package.json" ]]; then
|
||||
SANKOFA_PUBLIC_WEB_SRC="${SANKOFA_PUBLIC_WEB_SRC:-$DEFAULT_SRC}"
|
||||
else
|
||||
SANKOFA_PUBLIC_WEB_SRC="${SANKOFA_PUBLIC_WEB_SRC:-}"
|
||||
fi
|
||||
|
||||
DRY_RUN=false
|
||||
[[ "${1:-}" == "--dry-run" ]] && DRY_RUN=true
|
||||
|
||||
echo "=== Sync Sankofa public (repo root) → CT ${VMID} (${CT_APP_DIR}) ==="
|
||||
echo "Proxmox: ${PROXMOX_HOST}"
|
||||
echo "Source: ${SANKOFA_PUBLIC_WEB_SRC:-<unset>}"
|
||||
echo ""
|
||||
|
||||
if [[ -z "$SANKOFA_PUBLIC_WEB_SRC" || ! -d "$SANKOFA_PUBLIC_WEB_SRC" ]]; then
|
||||
echo "ERROR: Set SANKOFA_PUBLIC_WEB_SRC to the Sankofa monorepo root (parent of portal/)."
|
||||
echo "Example: SANKOFA_PUBLIC_WEB_SRC=/path/to/Sankofa $0"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v tar >/dev/null; then
|
||||
echo "ERROR: tar required"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TMP_TGZ="${TMPDIR:-/tmp}/sankofa-public-web-sync-$$.tgz"
|
||||
REMOTE_TGZ="/tmp/sankofa-public-web-sync-$$.tgz"
|
||||
CT_TGZ="/tmp/sankofa-public-web-sync.tgz"
|
||||
|
||||
cleanup() { rm -f "$TMP_TGZ"; }
|
||||
trap cleanup EXIT
|
||||
|
||||
if $DRY_RUN; then
|
||||
echo "[DRY-RUN] tar (exclude node_modules,.next,.git) → $TMP_TGZ"
|
||||
echo "[DRY-RUN] scp → root@${PROXMOX_HOST}:${REMOTE_TGZ}"
|
||||
echo "[DRY-RUN] pct push ${VMID} … && systemctl stop ${SERVICE_NAME}"
|
||||
echo "[DRY-RUN] pnpm install && pnpm build && systemctl start ${SERVICE_NAME}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "📦 Archiving Sankofa repo root (excluding node_modules, .next, .git, .env / .env.local)…"
|
||||
tar czf "$TMP_TGZ" \
|
||||
--exclude=node_modules \
|
||||
--exclude=.next \
|
||||
--exclude=portal/node_modules \
|
||||
--exclude=portal/.next \
|
||||
--exclude=.git \
|
||||
--exclude=.env.local \
|
||||
--exclude=.env \
|
||||
-C "$SANKOFA_PUBLIC_WEB_SRC" .
|
||||
|
||||
echo "📤 Copy to Proxmox host…"
|
||||
scp $SSH_OPTS "$TMP_TGZ" "root@${PROXMOX_HOST}:${REMOTE_TGZ}"
|
||||
|
||||
echo "📥 Push into CT ${VMID} and build…"
|
||||
ssh $SSH_OPTS "root@${PROXMOX_HOST}" bash -s <<REMOTE_EOF
|
||||
set -euo pipefail
|
||||
pct push ${VMID} ${REMOTE_TGZ} ${CT_TGZ}
|
||||
rm -f ${REMOTE_TGZ}
|
||||
pct exec ${VMID} -- systemctl stop ${SERVICE_NAME} || true
|
||||
pct exec ${VMID} -- bash -lc 'set -euo pipefail
|
||||
mkdir -p ${CT_APP_DIR}
|
||||
cd ${CT_APP_DIR}
|
||||
tar xzf ${CT_TGZ}
|
||||
rm -f ${CT_TGZ}
|
||||
command -v pnpm >/dev/null || { echo "ERROR: pnpm missing in CT"; exit 1; }
|
||||
pnpm install
|
||||
pnpm build
|
||||
'
|
||||
pct exec ${VMID} -- systemctl start ${SERVICE_NAME}
|
||||
pct exec ${VMID} -- systemctl is-active ${SERVICE_NAME}
|
||||
REMOTE_EOF
|
||||
|
||||
echo ""
|
||||
echo "✅ Done. Point NPM apex with IP_SANKOFA_PUBLIC_WEB / SANKOFA_PUBLIC_WEB_PORT, then:"
|
||||
echo " bash scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh"
|
||||
echo " curl -sS http://${IP_SANKOFA_PUBLIC_WEB:-<CT_IP>}:${SANKOFA_PUBLIC_WEB_PORT:-3000}/ | head -c 120"
|
||||
@@ -284,24 +284,34 @@ create_proxy_host() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# Configure all 19 domains
|
||||
echo "🚀 Starting domain configuration (19 domains)..."
|
||||
# Configure core domains (count varies; sankofa zone includes portal/admin/dash when dash IP set)
|
||||
echo "🚀 Starting domain configuration..."
|
||||
echo ""
|
||||
|
||||
SUCCESS=0
|
||||
FAILED=0
|
||||
|
||||
# sankofa.nexus (5 domains) — portal :3000 / Phoenix API :4000 (not Blockscout; explorer is IP_BLOCKSCOUT:80)
|
||||
# sankofa.nexus zone — corporate apex (IP_SANKOFA_PUBLIC_WEB), Phoenix API :4000, client SSO (portal/admin), optional dash (IP_SANKOFA_DASH). Not Blockscout.
|
||||
IP_SANKOFA_PORTAL="${IP_SANKOFA_PORTAL:-${IP_SERVICE_51:-192.168.11.51}}"
|
||||
IP_SANKOFA_PHOENIX_API="${IP_SANKOFA_PHOENIX_API:-${IP_SERVICE_50:-192.168.11.50}}"
|
||||
SANKOFA_PORTAL_PORT="${SANKOFA_PORTAL_PORT:-3000}"
|
||||
SANKOFA_PHOENIX_API_PORT="${SANKOFA_PHOENIX_API_PORT:-4000}"
|
||||
IP_SANKOFA_PUBLIC_WEB="${IP_SANKOFA_PUBLIC_WEB:-${IP_SANKOFA_PORTAL}}"
|
||||
SANKOFA_PUBLIC_WEB_PORT="${SANKOFA_PUBLIC_WEB_PORT:-${SANKOFA_PORTAL_PORT}}"
|
||||
IP_SANKOFA_CLIENT_SSO="${IP_SANKOFA_CLIENT_SSO:-${IP_SANKOFA_PORTAL}}"
|
||||
SANKOFA_CLIENT_SSO_PORT="${SANKOFA_CLIENT_SSO_PORT:-${SANKOFA_PORTAL_PORT}}"
|
||||
IP_ORDER_HAPROXY="${IP_ORDER_HAPROXY:-192.168.11.39}"
|
||||
create_proxy_host "sankofa.nexus" "http" "${IP_SANKOFA_PORTAL}" "${SANKOFA_PORTAL_PORT}" "false" && ((SUCCESS++)) || ((FAILED++))
|
||||
create_proxy_host "www.sankofa.nexus" "http" "${IP_SANKOFA_PORTAL}" "${SANKOFA_PORTAL_PORT}" "false" && ((SUCCESS++)) || ((FAILED++))
|
||||
create_proxy_host "sankofa.nexus" "http" "${IP_SANKOFA_PUBLIC_WEB}" "${SANKOFA_PUBLIC_WEB_PORT}" "false" && ((SUCCESS++)) || ((FAILED++))
|
||||
create_proxy_host "www.sankofa.nexus" "http" "${IP_SANKOFA_PUBLIC_WEB}" "${SANKOFA_PUBLIC_WEB_PORT}" "false" && ((SUCCESS++)) || ((FAILED++))
|
||||
create_proxy_host "phoenix.sankofa.nexus" "http" "${IP_SANKOFA_PHOENIX_API}" "${SANKOFA_PHOENIX_API_PORT}" "false" && ((SUCCESS++)) || ((FAILED++))
|
||||
create_proxy_host "www.phoenix.sankofa.nexus" "http" "${IP_SANKOFA_PHOENIX_API}" "${SANKOFA_PHOENIX_API_PORT}" "false" && ((SUCCESS++)) || ((FAILED++))
|
||||
create_proxy_host "the-order.sankofa.nexus" "http" "${IP_ORDER_HAPROXY}" "80" "false" && ((SUCCESS++)) || ((FAILED++))
|
||||
create_proxy_host "portal.sankofa.nexus" "http" "${IP_SANKOFA_CLIENT_SSO}" "${SANKOFA_CLIENT_SSO_PORT}" "false" && ((SUCCESS++)) || ((FAILED++))
|
||||
create_proxy_host "admin.sankofa.nexus" "http" "${IP_SANKOFA_CLIENT_SSO}" "${SANKOFA_CLIENT_SSO_PORT}" "false" && ((SUCCESS++)) || ((FAILED++))
|
||||
if [[ -n "${IP_SANKOFA_DASH:-}" ]]; then
|
||||
SANKOFA_DASH_PORT="${SANKOFA_DASH_PORT:-3000}"
|
||||
create_proxy_host "dash.sankofa.nexus" "http" "${IP_SANKOFA_DASH}" "${SANKOFA_DASH_PORT}" "false" && ((SUCCESS++)) || ((FAILED++))
|
||||
fi
|
||||
|
||||
# d-bis.org (9 domains)
|
||||
create_proxy_host "explorer.d-bis.org" "http" "${IP_BLOCKSCOUT:-${IP_DEVICE_14:-${IP_DEVICE_14:-${IP_DEVICE_14:-${IP_DEVICE_14:-${IP_DEVICE_14:-192.168.11.14}}}}}0}" "80" "false" && ((SUCCESS++)) || ((FAILED++))
|
||||
|
||||
@@ -373,15 +373,19 @@ update_proxy_host "dbis.xom-dev.phoenix.sankofa.nexus" "http://${IP_GOV_PORTALS_
|
||||
update_proxy_host "iccc.xom-dev.phoenix.sankofa.nexus" "http://${IP_GOV_PORTALS_DEV}:3002" false && updated_count=$((updated_count + 1)) || { add_proxy_host "iccc.xom-dev.phoenix.sankofa.nexus" "${IP_GOV_PORTALS_DEV}" 3002 false false && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
update_proxy_host "omnl.xom-dev.phoenix.sankofa.nexus" "http://${IP_GOV_PORTALS_DEV}:3003" false && updated_count=$((updated_count + 1)) || { add_proxy_host "omnl.xom-dev.phoenix.sankofa.nexus" "${IP_GOV_PORTALS_DEV}" 3003 false false && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
update_proxy_host "xom.xom-dev.phoenix.sankofa.nexus" "http://${IP_GOV_PORTALS_DEV}:3004" false && updated_count=$((updated_count + 1)) || { add_proxy_host "xom.xom-dev.phoenix.sankofa.nexus" "${IP_GOV_PORTALS_DEV}" 3004 false false && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
# Sankofa portal (Next.js CT 7801) and Phoenix API (Fastify CT 7800) — not Blockscout / SolaceScanScout (that is explorer.d-bis.org / IP_BLOCKSCOUT:80)
|
||||
# Public web intent: sankofa.nexus = Sankofa Sovereign Technologies; phoenix.sankofa.nexus = Phoenix Cloud Services (division). Client SSO: admin / portal + keycloak IdP. Operator: dash (IP+MFA). See docs/02-architecture/EXPECTED_WEB_CONTENT.md.
|
||||
# Sankofa / Phoenix — not Blockscout (explorer.d-bis.org / IP_BLOCKSCOUT:80).
|
||||
# Intent: sankofa.nexus = corporate marketing (IP_SANKOFA_PUBLIC_WEB); portal.sankofa.nexus + admin = client SSO (IP_SANKOFA_CLIENT_SSO); phoenix = division + API. dash = operator (set IP_SANKOFA_DASH to manage). See docs/02-architecture/EXPECTED_WEB_CONTENT.md.
|
||||
# www.sankofa.nexus → 301 https://sankofa.nexus$request_uri; www.phoenix → phoenix; www.the-order → the-order (NPM advanced_config).
|
||||
IP_SANKOFA_PORTAL="${IP_SANKOFA_PORTAL:-${IP_SERVICE_51:-192.168.11.51}}"
|
||||
IP_SANKOFA_PHOENIX_API="${IP_SANKOFA_PHOENIX_API:-${IP_SERVICE_50:-192.168.11.50}}"
|
||||
SANKOFA_PORTAL_PORT="${SANKOFA_PORTAL_PORT:-3000}"
|
||||
SANKOFA_PHOENIX_API_PORT="${SANKOFA_PHOENIX_API_PORT:-4000}"
|
||||
update_proxy_host "sankofa.nexus" "http://${IP_SANKOFA_PORTAL}:${SANKOFA_PORTAL_PORT}" false false && updated_count=$((updated_count + 1)) || { add_proxy_host "sankofa.nexus" "${IP_SANKOFA_PORTAL}" "${SANKOFA_PORTAL_PORT}" false false && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
update_proxy_host "www.sankofa.nexus" "http://${IP_SANKOFA_PORTAL}:${SANKOFA_PORTAL_PORT}" false false "https://sankofa.nexus" && updated_count=$((updated_count + 1)) || { add_proxy_host "www.sankofa.nexus" "${IP_SANKOFA_PORTAL}" "${SANKOFA_PORTAL_PORT}" false false "https://sankofa.nexus" && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
IP_SANKOFA_PUBLIC_WEB="${IP_SANKOFA_PUBLIC_WEB:-${IP_SANKOFA_PORTAL}}"
|
||||
SANKOFA_PUBLIC_WEB_PORT="${SANKOFA_PUBLIC_WEB_PORT:-${SANKOFA_PORTAL_PORT}}"
|
||||
IP_SANKOFA_CLIENT_SSO="${IP_SANKOFA_CLIENT_SSO:-${IP_SANKOFA_PORTAL}}"
|
||||
SANKOFA_CLIENT_SSO_PORT="${SANKOFA_CLIENT_SSO_PORT:-${SANKOFA_PORTAL_PORT}}"
|
||||
update_proxy_host "sankofa.nexus" "http://${IP_SANKOFA_PUBLIC_WEB}:${SANKOFA_PUBLIC_WEB_PORT}" false false && updated_count=$((updated_count + 1)) || { add_proxy_host "sankofa.nexus" "${IP_SANKOFA_PUBLIC_WEB}" "${SANKOFA_PUBLIC_WEB_PORT}" false false && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
update_proxy_host "www.sankofa.nexus" "http://${IP_SANKOFA_PUBLIC_WEB}:${SANKOFA_PUBLIC_WEB_PORT}" false false "https://sankofa.nexus" && updated_count=$((updated_count + 1)) || { add_proxy_host "www.sankofa.nexus" "${IP_SANKOFA_PUBLIC_WEB}" "${SANKOFA_PUBLIC_WEB_PORT}" false false "https://sankofa.nexus" && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
update_proxy_host "phoenix.sankofa.nexus" "http://${IP_SANKOFA_PHOENIX_API}:${SANKOFA_PHOENIX_API_PORT}" false false && updated_count=$((updated_count + 1)) || { add_proxy_host "phoenix.sankofa.nexus" "${IP_SANKOFA_PHOENIX_API}" "${SANKOFA_PHOENIX_API_PORT}" false false && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
update_proxy_host "www.phoenix.sankofa.nexus" "http://${IP_SANKOFA_PHOENIX_API}:${SANKOFA_PHOENIX_API_PORT}" false false "https://phoenix.sankofa.nexus" && updated_count=$((updated_count + 1)) || { add_proxy_host "www.phoenix.sankofa.nexus" "${IP_SANKOFA_PHOENIX_API}" "${SANKOFA_PHOENIX_API_PORT}" false false "https://phoenix.sankofa.nexus" && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
# Keycloak (CT 7802) — portal SSO; NPM must forward X-Forwarded-* (Keycloak KC_PROXY_HEADERS=xforwarded on upstream)
|
||||
@@ -403,6 +407,16 @@ IP_SANKOFA_STUDIO="${IP_SANKOFA_STUDIO:-192.168.11.72}"
|
||||
SANKOFA_STUDIO_PORT="${SANKOFA_STUDIO_PORT:-8000}"
|
||||
# block_exploits false — studio UI/API may POST; align with portal policy (avoid spurious 405 from NPM WAF)
|
||||
update_proxy_host "studio.sankofa.nexus" "http://${IP_SANKOFA_STUDIO}:${SANKOFA_STUDIO_PORT}" false false && updated_count=$((updated_count + 1)) || { add_proxy_host "studio.sankofa.nexus" "${IP_SANKOFA_STUDIO}" "${SANKOFA_STUDIO_PORT}" false false && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
# Client SSO hostnames (Next.js portal stack on 7801 typical). NEXTAUTH_URL / Keycloak redirects: https://portal.sankofa.nexus (and https://admin.sankofa.nexus).
|
||||
update_proxy_host "portal.sankofa.nexus" "http://${IP_SANKOFA_CLIENT_SSO}:${SANKOFA_CLIENT_SSO_PORT}" false false && updated_count=$((updated_count + 1)) || { add_proxy_host "portal.sankofa.nexus" "${IP_SANKOFA_CLIENT_SSO}" "${SANKOFA_CLIENT_SSO_PORT}" false false && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
update_proxy_host "admin.sankofa.nexus" "http://${IP_SANKOFA_CLIENT_SSO}:${SANKOFA_CLIENT_SSO_PORT}" false false && updated_count=$((updated_count + 1)) || { add_proxy_host "admin.sankofa.nexus" "${IP_SANKOFA_CLIENT_SSO}" "${SANKOFA_CLIENT_SSO_PORT}" false false && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
# Operator systems dashboard — only when IP_SANKOFA_DASH is set (see config/ip-addresses.conf).
|
||||
if [[ -n "${IP_SANKOFA_DASH:-}" ]]; then
|
||||
SANKOFA_DASH_PORT="${SANKOFA_DASH_PORT:-3000}"
|
||||
update_proxy_host "dash.sankofa.nexus" "http://${IP_SANKOFA_DASH}:${SANKOFA_DASH_PORT}" false false && updated_count=$((updated_count + 1)) || { add_proxy_host "dash.sankofa.nexus" "${IP_SANKOFA_DASH}" "${SANKOFA_DASH_PORT}" false false && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
else
|
||||
echo "ℹ️ Skipping dash.sankofa.nexus (set IP_SANKOFA_DASH and SANKOFA_DASH_PORT to provision upstream)."
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
@@ -330,6 +330,10 @@ main() {
|
||||
SANKOFA_RECORDS=(
|
||||
"@" # sankofa.nexus
|
||||
"www" # www.sankofa.nexus
|
||||
"portal" # portal.sankofa.nexus (client SSO)
|
||||
"admin" # admin.sankofa.nexus (client access admin)
|
||||
"keycloak" # keycloak.sankofa.nexus (IdP)
|
||||
"studio" # studio.sankofa.nexus (FusionAI Creator)
|
||||
"phoenix" # phoenix.sankofa.nexus
|
||||
"www.phoenix" # www.phoenix.sankofa.nexus
|
||||
"the-order" # the-order.sankofa.nexus
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Update Sankofa NPMplus proxy hosts (portal + Phoenix API + the-order) via API by numeric host ID.
|
||||
# Prefer for production: scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh (domain-based, full fleet).
|
||||
# Update Sankofa NPMplus proxy hosts (apex + Phoenix API + the-order) via API by numeric host ID.
|
||||
# Prefer for production: scripts/nginx-proxy-manager/update-npmplus-proxy-hosts-api.sh (domain-based; includes portal.sankofa.nexus, admin.sankofa.nexus, dash when IP_SANKOFA_DASH set).
|
||||
# NPM proxy host IDs below match backup backup-20260325_183932 (3–6, 7, 59); override with SANKOFA_NPM_ID_* if your DB differs.
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
@@ -27,6 +27,8 @@ IP_SANKOFA_PORTAL="${IP_SANKOFA_PORTAL:-${IP_SERVICE_51:-192.168.11.51}}"
|
||||
IP_SANKOFA_PHOENIX_API="${IP_SANKOFA_PHOENIX_API:-${IP_SERVICE_50:-192.168.11.50}}"
|
||||
SANKOFA_PORTAL_PORT="${SANKOFA_PORTAL_PORT:-3000}"
|
||||
SANKOFA_PHOENIX_API_PORT="${SANKOFA_PHOENIX_API_PORT:-4000}"
|
||||
IP_SANKOFA_PUBLIC_WEB="${IP_SANKOFA_PUBLIC_WEB:-$IP_SANKOFA_PORTAL}"
|
||||
SANKOFA_PUBLIC_WEB_PORT="${SANKOFA_PUBLIC_WEB_PORT:-$SANKOFA_PORTAL_PORT}"
|
||||
IP_ORDER_HAPROXY="${IP_ORDER_HAPROXY:-192.168.11.39}"
|
||||
THE_ORDER_UPSTREAM_IP="${THE_ORDER_UPSTREAM_IP:-${IP_ORDER_HAPROXY}}"
|
||||
THE_ORDER_UPSTREAM_PORT="${THE_ORDER_UPSTREAM_PORT:-80}"
|
||||
@@ -41,8 +43,8 @@ SANKOFA_NPM_ID_WWW_THE_ORDER="${SANKOFA_NPM_ID_WWW_THE_ORDER:-59}"
|
||||
|
||||
# Optional 4th field: canonical HTTPS apex — NPM advanced_config 301 (www → apex). Matches update-npmplus-proxy-hosts-api.sh.
|
||||
declare -A PROXY_HOSTS=(
|
||||
["$SANKOFA_NPM_ID_ROOT"]="sankofa.nexus|${IP_SANKOFA_PORTAL}|${SANKOFA_PORTAL_PORT}|"
|
||||
["$SANKOFA_NPM_ID_WWW"]="www.sankofa.nexus|${IP_SANKOFA_PORTAL}|${SANKOFA_PORTAL_PORT}|https://sankofa.nexus"
|
||||
["$SANKOFA_NPM_ID_ROOT"]="sankofa.nexus|${IP_SANKOFA_PUBLIC_WEB}|${SANKOFA_PUBLIC_WEB_PORT}|"
|
||||
["$SANKOFA_NPM_ID_WWW"]="www.sankofa.nexus|${IP_SANKOFA_PUBLIC_WEB}|${SANKOFA_PUBLIC_WEB_PORT}|https://sankofa.nexus"
|
||||
["$SANKOFA_NPM_ID_PHOENIX"]="phoenix.sankofa.nexus|${IP_SANKOFA_PHOENIX_API}|${SANKOFA_PHOENIX_API_PORT}|"
|
||||
["$SANKOFA_NPM_ID_WWW_PHOENIX"]="www.phoenix.sankofa.nexus|${IP_SANKOFA_PHOENIX_API}|${SANKOFA_PHOENIX_API_PORT}|https://phoenix.sankofa.nexus"
|
||||
["$SANKOFA_NPM_ID_THE_ORDER"]="the-order.sankofa.nexus|${THE_ORDER_UPSTREAM_IP}|${THE_ORDER_UPSTREAM_PORT}|"
|
||||
|
||||
Reference in New Issue
Block a user