Add explorer-live deploy target and operator handoff
Some checks failed
Deploy to Phoenix / validate (push) Failing after 13s
Deploy to Phoenix / deploy (push) Has been skipped
Deploy to Phoenix / deploy-atomic-swap-dapp (push) Has been skipped
Deploy to Phoenix / cloudflare (push) Has been skipped

This commit is contained in:
Codex
2026-04-23 09:53:49 -07:00
parent 77d40201a3
commit 453ccc8d12
7 changed files with 416 additions and 0 deletions

View File

@@ -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.

View File

@@ -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)

View File

@@ -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=<live operator 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=<live operator 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=<new 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.

View File

@@ -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 (34 nodes), order of operations
- **[ER605_ROUTER_CONFIGURATION.md](ER605_ROUTER_CONFIGURATION.md)** ⭐⭐ - ER605 router configuration

View File

@@ -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 13:** [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) |

View File

@@ -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",

View File

@@ -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."