Files
proxmox/docs/04-configuration/PHOENIX_SANKOFA_OPERATOR_HANDOFF.md

8.5 KiB

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:

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:

Rotate / reload / verify

A. Rotate PHOENIX_DEPLOY_SECRET on CT 5700

Run from a host with guest or pct exec access:

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:

NEW_KEY="$(openssl rand -hex 32)"
echo "NEW PHOENIX_RAILING_API_KEY=$NEW_KEY"

Update CT 5700:

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:

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

curl -fsS http://192.168.11.59:4001/health

2. Phoenix partner-key health summary from CT 7800

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

pct exec 7800 -- curl -fsS http://127.0.0.1:4000/health

4. Inspect deploy targets on CT 5700

curl -fsS http://192.168.11.59:4001/api/deploy-targets | jq .

To confirm explorer-live specifically:

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:

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

curl -fsS https://blockscout.defi-oracle.io/api/config/capabilities

Optional public smoke:

bash scripts/verify/check-explorer-e2e.sh https://blockscout.defi-oracle.io

Files and commands to remember

Live files

Core systemd services

  • CT 5700: phoenix-deploy-api
  • CT 7800: sankofa-api

Useful status commands

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.