From 453ccc8d1298f15345c1e6f2afc943b564fb89da Mon Sep 17 00:00:00 2001 From: Codex Date: Thu, 23 Apr 2026 09:53:49 -0700 Subject: [PATCH] Add explorer-live deploy target and operator handoff --- .../DEVIN_GITEA_PROXMOX_CICD.md | 6 + .../PHOENIX_DEPLOY_API_GITEA_INTEGRATION.md | 3 + .../PHOENIX_SANKOFA_OPERATOR_HANDOFF.md | 272 ++++++++++++++++++ docs/04-configuration/README.md | 1 + docs/MASTER_INDEX.md | 1 + phoenix-deploy-api/deploy-targets.json | 48 ++++ ...nix-deploy-explorer-live-from-workspace.sh | 85 ++++++ 7 files changed, 416 insertions(+) create mode 100644 docs/04-configuration/PHOENIX_SANKOFA_OPERATOR_HANDOFF.md create mode 100755 scripts/deployment/phoenix-deploy-explorer-live-from-workspace.sh diff --git a/docs/04-configuration/DEVIN_GITEA_PROXMOX_CICD.md b/docs/04-configuration/DEVIN_GITEA_PROXMOX_CICD.md index 5cbbdaaf..44a30d5d 100644 --- a/docs/04-configuration/DEVIN_GITEA_PROXMOX_CICD.md +++ b/docs/04-configuration/DEVIN_GITEA_PROXMOX_CICD.md @@ -3,6 +3,8 @@ **Status:** Working baseline for this repo **Last Updated:** 2026-04-20 +**Operator handoff:** [PHOENIX_SANKOFA_OPERATOR_HANDOFF.md](PHOENIX_SANKOFA_OPERATOR_HANDOFF.md) + ## Goal Create a repeatable path where: @@ -33,6 +35,10 @@ A second target is now available: - `portal-live` → runs [sync-sankofa-portal-7801.sh](/home/intlc/projects/proxmox/scripts/deployment/sync-sankofa-portal-7801.sh) and then checks `http://192.168.11.51:3000/` +An additional live app target is now available: + +- `explorer-live` for `d-bis/explorer-monorepo` → redeploys the live explorer stack on VMID `5000` + ## Workflow lockstep Because both `main` and `master` can trigger deploys, deploy behavior is now defined from canonical source files and checked for branch parity. diff --git a/docs/04-configuration/PHOENIX_DEPLOY_API_GITEA_INTEGRATION.md b/docs/04-configuration/PHOENIX_DEPLOY_API_GITEA_INTEGRATION.md index 9d97acce..bb65c318 100644 --- a/docs/04-configuration/PHOENIX_DEPLOY_API_GITEA_INTEGRATION.md +++ b/docs/04-configuration/PHOENIX_DEPLOY_API_GITEA_INTEGRATION.md @@ -5,6 +5,8 @@ --- +**Operator handoff:** [PHOENIX_SANKOFA_OPERATOR_HANDOFF.md](PHOENIX_SANKOFA_OPERATOR_HANDOFF.md) — live CT locations, secrets split, rotate/reload/verify commands, and current verified scope. + ## Overview The Phoenix Deploy API ([phoenix-deploy-api/](../../phoenix-deploy-api/)) receives Gitea webhooks and provides a deploy endpoint for triggering Phoenix deployments from Gitea Actions or external tools. @@ -92,6 +94,7 @@ Current repo-shipped targets include: - `default` for `d-bis/proxmox` → publish `phoenix-deploy-api` to VMID `5700` - `portal-live` for `d-bis/proxmox` → run `scripts/deployment/sync-sankofa-portal-7801.sh` and verify `http://192.168.11.51:3000/` +- `explorer-live` for `d-bis/explorer-monorepo` → sync staged workspace and redeploy the live explorer stack on VMID `5000` ## Public-sector program manifest (runtime) diff --git a/docs/04-configuration/PHOENIX_SANKOFA_OPERATOR_HANDOFF.md b/docs/04-configuration/PHOENIX_SANKOFA_OPERATOR_HANDOFF.md new file mode 100644 index 00000000..bd9c2db8 --- /dev/null +++ b/docs/04-configuration/PHOENIX_SANKOFA_OPERATOR_HANDOFF.md @@ -0,0 +1,272 @@ +# Phoenix / Sankofa Operator Handoff + +**Last Updated:** 2026-04-23 +**Status:** Live wiring confirmed for Gitea Actions -> Phoenix Deploy API -> Sankofa server-to-server health/railing path + +## Purpose + +This is the operator handoff for the live Phoenix deploy path and the Sankofa-side server-to-server integration. + +It records: + +- where the live services and env files are +- which secret lives on which host +- how to rotate and reload safely +- how to verify the current production path + +This document is about the live deploy/control-plane plumbing. It is not a full app-auth runbook for the public `phoenix.sankofa.nexus` user flow. + +## Live topology + +### CT 5700 — Phoenix Deploy API / Gitea runner host + +- **Role:** Phoenix Deploy API, Gitea Actions execution support, deploy target resolver +- **CT / IP:** `5700` / `192.168.11.59` +- **Primary service:** `phoenix-deploy-api` +- **Primary env file:** `/opt/phoenix-deploy-api/.env` +- **Key live vars:** + - `PHOENIX_DEPLOY_SECRET` + - `PHOENIX_PARTNER_KEYS` + - `PHOENIX_REPO_ROOT` + - `GITEA_TOKEN` + +### CT 7800 — Sankofa API + +- **Role:** Sankofa API server-side caller into Phoenix Deploy API / Phoenix railing +- **CT / node:** `7800` on `r630-01` (`192.168.11.11`) +- **Primary service:** `sankofa-api` +- **Primary env file:** `/opt/sankofa-api/.env` +- **Key live vars:** + - `PHOENIX_RAILING_URL=http://192.168.11.59:4001` + - `PHOENIX_RAILING_API_KEY=` + +### Gitea repo secrets + +For repos that trigger deploys through Actions, configure: + +- `PHOENIX_DEPLOY_URL` +- `PHOENIX_DEPLOY_TOKEN` + +Confirmed present in: + +- `d-bis/proxmox` + +Explorer live redeploy now also expects the same secret pair in the repo that owns the workflow: + +- `d-bis/explorer-monorepo` + +## Current proven chain + +The following live path is confirmed as of **2026-04-23**: + +1. Gitea Actions can call Phoenix Deploy API with repo secret pair. +2. Phoenix Deploy API on CT `5700` has: + - `PHOENIX_DEPLOY_SECRET` + - `PHOENIX_PARTNER_KEYS` + - deploy target map including `explorer-live` +3. Sankofa API on CT `7800` has: + - `PHOENIX_RAILING_URL=http://192.168.11.59:4001` + - `PHOENIX_RAILING_API_KEY=` +4. Sankofa API can reach Phoenix Deploy API from inside CT `7800`. +5. Phoenix Deploy API `GET /api/v1/health/summary` returns healthy JSON when called with the Sankofa-side API key. + +## Not yet proven + +The following is **not** covered by the server-to-server verification above: + +- authenticated end-user Phoenix app flow through `https://phoenix.sankofa.nexus` +- browser/session/auth behavior above the raw API-key integration + +Treat that as a separate application/auth verification task. + +## Explorer live redeploy target + +Phoenix Deploy API now includes: + +- repo: `d-bis/explorer-monorepo` +- target: `explorer-live` + +The target runs the wrapper: + +- [scripts/deployment/phoenix-deploy-explorer-live-from-workspace.sh](/home/intlc/projects/proxmox/scripts/deployment/phoenix-deploy-explorer-live-from-workspace.sh:1) + +That wrapper syncs the staged Gitea checkout into: + +- `${PHOENIX_REPO_ROOT}/explorer-monorepo` + +Then runs the canonical deploy order: + +1. `bash scripts/deploy-explorer-config-to-vmid5000.sh` +2. `bash scripts/deploy-explorer-ai-to-vmid5000.sh` +3. `bash scripts/deploy-next-frontend-to-vmid5000.sh` + +The Gitea workflow in the explorer repo is: + +- [deploy-live.yml](/home/intlc/projects/proxmox/explorer-monorepo/.gitea/workflows/deploy-live.yml:1) + +## Rotate / reload / verify + +### A. Rotate `PHOENIX_DEPLOY_SECRET` on CT 5700 + +Run from a host with guest or `pct exec` access: + +```bash +pct exec 5700 -- sh -c 'cp -a /opt/phoenix-deploy-api/.env /opt/phoenix-deploy-api/.env.bak.$(date +%Y%m%d_%H%M%S)' +NEW_SECRET="$(openssl rand -hex 32)" +echo "NEW PHOENIX_DEPLOY_TOKEN=$NEW_SECRET" +pct exec 5700 -- env NEW_SECRET="$NEW_SECRET" sh -c ' + awk '"'"'!/^PHOENIX_DEPLOY_SECRET=/'"'"' /opt/phoenix-deploy-api/.env > /tmp/phoenix-deploy-api.env && + printf "PHOENIX_DEPLOY_SECRET=%s\n" "$NEW_SECRET" >> /tmp/phoenix-deploy-api.env && + mv /tmp/phoenix-deploy-api.env /opt/phoenix-deploy-api/.env +' +pct exec 5700 -- systemctl restart phoenix-deploy-api +pct exec 5700 -- systemctl is-active phoenix-deploy-api +``` + +Then update every caller that uses the bearer deploy token: + +- Gitea repo secret `PHOENIX_DEPLOY_TOKEN` +- any local operator `.env` +- any direct deploy trigger scripts or webhooks still using the old value + +### B. Rotate Sankofa -> Phoenix server key on CT 7800 + +This is the key stored as: + +- `PHOENIX_RAILING_API_KEY` in `/opt/sankofa-api/.env` + +It must also remain present in Phoenix Deploy API partner-key configuration: + +- `PHOENIX_PARTNER_KEYS` in `/opt/phoenix-deploy-api/.env` + +Safe sequence: + +1. Add the new key to `PHOENIX_PARTNER_KEYS` on CT `5700` without removing the old one yet. +2. Restart `phoenix-deploy-api`. +3. Update `PHOENIX_RAILING_API_KEY` on CT `7800`. +4. Restart `sankofa-api`. +5. Verify from CT `7800`. +6. Remove the old key from `PHOENIX_PARTNER_KEYS` only after success. + +Example: + +```bash +NEW_KEY="$(openssl rand -hex 32)" +echo "NEW PHOENIX_RAILING_API_KEY=$NEW_KEY" +``` + +Update CT `5700`: + +```bash +pct exec 5700 -- sh -c 'cp -a /opt/phoenix-deploy-api/.env /opt/phoenix-deploy-api/.env.bak.$(date +%Y%m%d_%H%M%S)' +# edit PHOENIX_PARTNER_KEYS to include the new key, then: +pct exec 5700 -- systemctl restart phoenix-deploy-api +pct exec 5700 -- systemctl is-active phoenix-deploy-api +``` + +Update CT `7800`: + +```bash +pct exec 7800 -- sh -c 'cp -a /opt/sankofa-api/.env /opt/sankofa-api/.env.bak.$(date +%Y%m%d_%H%M%S)' +# edit /opt/sankofa-api/.env and set PHOENIX_RAILING_API_KEY=, then: +pct exec 7800 -- systemctl restart sankofa-api +pct exec 7800 -- systemctl is-active sankofa-api +``` + +### C. Reload after deploy-target changes on CT 5700 + +When `phoenix-deploy-api/deploy-targets.json` changes in the repo, redeploy or reinstall the Phoenix Deploy API bundle to CT `5700` so the live service gets the updated file. + +Quick path from the proxmox repo root: + +```bash +bash phoenix-deploy-api/scripts/install-systemd.sh +systemctl restart phoenix-deploy-api +systemctl is-active phoenix-deploy-api +``` + +If running from the Proxmox host into CT `5700`, use the local service path installed there instead of assuming the repo checkout is on the guest. + +## Verification commands + +### 1. Phoenix Deploy API health on CT 5700 + +```bash +curl -fsS http://192.168.11.59:4001/health +``` + +### 2. Phoenix partner-key health summary from CT 7800 + +```bash +RAIL_KEY="$(pct exec 7800 -- sh -lc "awk -F= '/^PHOENIX_RAILING_API_KEY=/{print \$2; exit}' /opt/sankofa-api/.env")" +curl -fsS http://192.168.11.59:4001/api/v1/health/summary \ + -H "X-API-Key: ${RAIL_KEY}" +``` + +### 3. Sankofa API local health on CT 7800 + +```bash +pct exec 7800 -- curl -fsS http://127.0.0.1:4000/health +``` + +### 4. Inspect deploy targets on CT 5700 + +```bash +curl -fsS http://192.168.11.59:4001/api/deploy-targets | jq . +``` + +To confirm `explorer-live` specifically: + +```bash +curl -fsS http://192.168.11.59:4001/api/deploy-targets | jq '.targets[] | select(.repo=="d-bis/explorer-monorepo")' +``` + +### 5. Trigger explorer live deploy manually + +Using the shared deploy token: + +```bash +curl -sSf -X POST http://192.168.11.59:4001/api/deploy \ + -H "Authorization: Bearer ${PHOENIX_DEPLOY_TOKEN}" \ + -H "Content-Type: application/json" \ + -d '{"repo":"d-bis/explorer-monorepo","branch":"master","target":"explorer-live"}' +``` + +### 6. Post-deploy explorer health + +```bash +curl -fsS https://blockscout.defi-oracle.io/api/config/capabilities +``` + +Optional public smoke: + +```bash +bash scripts/verify/check-explorer-e2e.sh https://blockscout.defi-oracle.io +``` + +## Files and commands to remember + +### Live files + +- CT `5700`: `/opt/phoenix-deploy-api/.env` +- CT `7800`: `/opt/sankofa-api/.env` +- Repo target map: [phoenix-deploy-api/deploy-targets.json](/home/intlc/projects/proxmox/phoenix-deploy-api/deploy-targets.json:127) +- Explorer workflow: [explorer-monorepo/.gitea/workflows/deploy-live.yml](/home/intlc/projects/proxmox/explorer-monorepo/.gitea/workflows/deploy-live.yml:1) + +### Core systemd services + +- CT `5700`: `phoenix-deploy-api` +- CT `7800`: `sankofa-api` + +### Useful status commands + +```bash +pct exec 5700 -- systemctl status phoenix-deploy-api --no-pager +pct exec 7800 -- systemctl status sankofa-api --no-pager +pct exec 5700 -- journalctl -u phoenix-deploy-api -n 100 --no-pager +pct exec 7800 -- journalctl -u sankofa-api -n 100 --no-pager +``` + +## Operator note + +The live deploy/control plane is now wired end to end. The remaining open validation item is the authenticated app-facing Phoenix flow through `phoenix.sankofa.nexus`, which should be tested separately as an application/auth scenario rather than a secret-wiring scenario. diff --git a/docs/04-configuration/README.md b/docs/04-configuration/README.md index 3751152f..8a104f45 100644 --- a/docs/04-configuration/README.md +++ b/docs/04-configuration/README.md @@ -26,6 +26,7 @@ This directory contains setup and configuration guides. - **[NPMPLUS_UI_APIERROR_400_RUNBOOK.md](NPMPLUS_UI_APIERROR_400_RUNBOOK.md)** - NPMplus UI ApiError 400 on dashboard load: find failing request, test API with curl, logs, fixes - **[E2E_DNS_FROM_LAN_RUNBOOK.md](E2E_DNS_FROM_LAN_RUNBOOK.md)** - Run E2E domain sweep from LAN when public DNS is unavailable: /etc/hosts option, DNS path, or bastion - **[E2E_ENDPOINTS_LIST.md](E2E_ENDPOINTS_LIST.md)** - All E2E verification endpoints (domain, type, URL); list from CLI: `./scripts/verify/verify-end-to-end-routing.sh --list-endpoints --profile=public` +- **[PHOENIX_SANKOFA_OPERATOR_HANDOFF.md](PHOENIX_SANKOFA_OPERATOR_HANDOFF.md)** - Live Phoenix Deploy API / Sankofa operator handoff: CT `5700`, CT `7800`, Gitea secret pair, `explorer-live`, and rotate/reload/verify commands - **[PROXMOX_LOAD_BALANCING_RUNBOOK.md](PROXMOX_LOAD_BALANCING_RUNBOOK.md)** - Balance Proxmox load: migrate containers from r630-01 to r630-02/ml110; candidates, script, cluster vs backup/restore - **[PROXMOX_ADD_THIRD_FOURTH_R630_DECISION.md](PROXMOX_ADD_THIRD_FOURTH_R630_DECISION.md)** - Add 3rd/4th R630 before migration? r630-03/04 status, HA/Ceph (3–4 nodes), order of operations - **[ER605_ROUTER_CONFIGURATION.md](ER605_ROUTER_CONFIGURATION.md)** ⭐⭐ - ER605 router configuration diff --git a/docs/MASTER_INDEX.md b/docs/MASTER_INDEX.md index 3a7d8a78..745de577 100644 --- a/docs/MASTER_INDEX.md +++ b/docs/MASTER_INDEX.md @@ -95,6 +95,7 @@ | **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); **DeFi Oracle Meta Mainnet (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) | | **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) | +| **Phoenix / Sankofa deploy handoff** | [04-configuration/PHOENIX_SANKOFA_OPERATOR_HANDOFF.md](04-configuration/PHOENIX_SANKOFA_OPERATOR_HANDOFF.md) — live CTs, env locations, secret split, rotate/reload/verify commands | | **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) | | **07-ccip** | [07-ccip/](07-ccip/), [00-meta/CW_BRIDGE_TASK_LIST.md](00-meta/CW_BRIDGE_TASK_LIST.md) | diff --git a/phoenix-deploy-api/deploy-targets.json b/phoenix-deploy-api/deploy-targets.json index f8eb1d53..5de67408 100644 --- a/phoenix-deploy-api/deploy-targets.json +++ b/phoenix-deploy-api/deploy-targets.json @@ -78,6 +78,30 @@ "timeout_ms": 10000 } }, + { + "repo": "d-bis/explorer-monorepo", + "target": "explorer-live", + "description": "Redeploy the live explorer stack on VMID 5000 from the staged explorer-monorepo checkout.", + "cwd": "${PHOENIX_REPO_ROOT}", + "command": [ + "bash", + "scripts/deployment/phoenix-deploy-explorer-live-from-workspace.sh" + ], + "required_env": [ + "PHOENIX_REPO_ROOT", + "PHOENIX_DEPLOY_WORKSPACE" + ], + "timeout_sec": 2400, + "healthcheck": { + "url": "https://blockscout.defi-oracle.io/api/config/capabilities", + "expect_status": 200, + "expect_body_includes": "\"chainId\"", + "attempts": 12, + "delay_ms": 5000, + "timeout_ms": 15000 + }, + "branch": "main" + }, { "repo": "d-bis/CurrenciCombo", "branch": "main", @@ -220,6 +244,30 @@ "timeout_ms": 10000 } }, + { + "repo": "d-bis/explorer-monorepo", + "target": "explorer-live", + "description": "Redeploy the live explorer stack on VMID 5000 from the staged explorer-monorepo checkout.", + "cwd": "${PHOENIX_REPO_ROOT}", + "command": [ + "bash", + "scripts/deployment/phoenix-deploy-explorer-live-from-workspace.sh" + ], + "required_env": [ + "PHOENIX_REPO_ROOT", + "PHOENIX_DEPLOY_WORKSPACE" + ], + "timeout_sec": 2400, + "healthcheck": { + "url": "https://blockscout.defi-oracle.io/api/config/capabilities", + "expect_status": 200, + "expect_body_includes": "\"chainId\"", + "attempts": 12, + "delay_ms": 5000, + "timeout_ms": 15000 + }, + "branch": "master" + }, { "repo": "d-bis/CurrenciCombo", "branch": "master", diff --git a/scripts/deployment/phoenix-deploy-explorer-live-from-workspace.sh b/scripts/deployment/phoenix-deploy-explorer-live-from-workspace.sh new file mode 100755 index 00000000..3c6840bd --- /dev/null +++ b/scripts/deployment/phoenix-deploy-explorer-live-from-workspace.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash +# Deploy explorer-monorepo live site from the Gitea-staged Phoenix workspace. +# +# phoenix-deploy-api stages non-Proxmox repos in PHOENIX_DEPLOY_WORKSPACE. The +# explorer deploy scripts expect the repo to live as PHOENIX_REPO_ROOT/explorer-monorepo +# because the API deploy bundles Proxmox reference docs. This wrapper syncs the staged +# tree into that layout, then runs the canonical live deploy scripts. + +set -euo pipefail + +die() { + echo "ERROR: $*" >&2 + exit 1 +} + +PHOENIX_REPO_ROOT="${PHOENIX_REPO_ROOT:-}" +PHOENIX_DEPLOY_WORKSPACE="${PHOENIX_DEPLOY_WORKSPACE:-}" +EXPLORER_REPO_DIR="${EXPLORER_REPO_DIR:-${PHOENIX_REPO_ROOT}/explorer-monorepo}" + +[[ -n "$PHOENIX_REPO_ROOT" ]] || die "PHOENIX_REPO_ROOT is required" +[[ -d "$PHOENIX_REPO_ROOT" ]] || die "PHOENIX_REPO_ROOT does not exist: $PHOENIX_REPO_ROOT" +[[ -n "$PHOENIX_DEPLOY_WORKSPACE" ]] || die "PHOENIX_DEPLOY_WORKSPACE is required" +[[ -d "$PHOENIX_DEPLOY_WORKSPACE" ]] || die "staged workspace missing: $PHOENIX_DEPLOY_WORKSPACE" +[[ "$EXPLORER_REPO_DIR" != "/" ]] || die "refusing to sync into /" + +echo "Syncing explorer workspace:" +echo " from: $PHOENIX_DEPLOY_WORKSPACE" +echo " to: $EXPLORER_REPO_DIR" + +mkdir -p "$EXPLORER_REPO_DIR" +rsync -a --delete \ + --exclude '.git/' \ + --exclude 'node_modules/' \ + --exclude 'frontend/node_modules/' \ + --exclude 'frontend/.next/' \ + --exclude 'backend/bin/' \ + --exclude 'test-results/' \ + "$PHOENIX_DEPLOY_WORKSPACE"/ "$EXPLORER_REPO_DIR"/ + +cd "$EXPLORER_REPO_DIR" + +FRONTEND_SCRIPT="$EXPLORER_REPO_DIR/scripts/deploy-next-frontend-to-vmid5000.sh" +if [[ -f "$FRONTEND_SCRIPT" ]] && ! grep -q 'FORCE_REMOTE_PCT' "$FRONTEND_SCRIPT"; then + python3 - "$FRONTEND_SCRIPT" <<'PY' +import pathlib +import sys + +path = pathlib.Path(sys.argv[1]) +text = path.read_text() +text = text.replace( + 'FRONTEND_PORT="${FRONTEND_PORT:-3000}"\n', + 'FRONTEND_PORT="${FRONTEND_PORT:-3000}"\nFORCE_REMOTE_PCT="${FORCE_REMOTE_PCT:-0}"\n', + 1, +) +text = text.replace( + 'if [[ -f /proc/1/cgroup ]] && grep -q "lxc" /proc/1/cgroup 2>/dev/null; then', + 'if [[ "$FORCE_REMOTE_PCT" != "1" ]] && [[ -f /proc/1/cgroup ]] && grep -q "lxc" /proc/1/cgroup 2>/dev/null; then', +) +path.write_text(text) +PY +fi + +export PROXMOX_HOST=192.168.11.12 +export PROXMOX_HOST_R630_02=192.168.11.12 +export EXEC_MODE=pct +export FORCE_REMOTE_PCT=1 + +if [[ ! -x "$EXPLORER_REPO_DIR/frontend/node_modules/.bin/next" ]]; then + echo "Installing frontend dependencies with npm ci" + ( + cd "$EXPLORER_REPO_DIR/frontend" + npm ci + ) +fi + +echo "Deploying static explorer config assets" +bash scripts/deploy-explorer-config-to-vmid5000.sh + +echo "Deploying explorer config/API backend" +bash scripts/deploy-explorer-ai-to-vmid5000.sh + +echo "Deploying Next frontend" +bash scripts/deploy-next-frontend-to-vmid5000.sh + +echo "Explorer live deployment complete."