Files
proxmox/phoenix-deploy-api/README.md
defiQUG b8613905bd
Some checks failed
Deploy to Phoenix / validate (push) Failing after 15s
Deploy to Phoenix / deploy (push) Has been skipped
chore: sync workspace — configs, docs, scripts, CI, pnpm, submodules
- Submodule pins: dbis_core, cross-chain-pmm-lps, mcp-proxmox (local, push may be pending), metamask-integration, smom-dbis-138
- Atomic swap + cross-chain-pmm-lops-publish, deploy-portal workflow, phoenix deploy-targets, routing/aggregator matrices
- Docs, token-lists, forge proxy, phoenix API, runbooks, verify scripts

Made-with: Cursor
2026-04-21 22:01:33 -07:00

6.0 KiB

Phoenix Deploy API

Gitea webhook receiver and deploy endpoint for Gitea → Phoenix / Proxmox deployment integration.

Endpoints

Method Path Description
POST /webhook/gitea Receives Gitea push/tag/PR webhooks; executes deploys only when PHOENIX_WEBHOOK_DEPLOY_ENABLED=1
POST /api/deploy Deploy request (repo, branch, target); resolves a target from deploy-targets.json and runs its command
GET /api/deploy-targets Lists configured deploy targets and whether each has a health check
GET /api/v1/infra/nodes Cluster nodes (Proxmox; stub if PROXMOX_* unset)
GET /api/v1/infra/storage Storage pools (Proxmox; stub if unset)
GET /api/v1/ve/vms List VMs/CTs (optional ?node=)
GET /api/v1/ve/vms/:node/:vmid/status VM/CT status (?type=lxc for containers)
POST /api/v1/ve/vms/:node/:vmid/start, stop, reboot VM/CT lifecycle (set PHOENIX_VE_LIFECYCLE_ENABLED=1)
GET /api/v1/health/metrics Prometheus query proxy (?query=<PromQL>)
GET /api/v1/health/alerts Active alerts (optional PROMETHEUS_ALERTS_URL)
GET /api/v1/health/summary Aggregated health for Portal
GET /api/v1/public-sector/programs Public-sector / eIDAS program manifest (JSON; no API key)
GET /health Health check

All /api/v1/* routes except GET /api/v1/public-sector/programs accept optional partner API key when PHOENIX_PARTNER_KEYS is set (X-API-Key or Authorization: Bearer <key>).

Environment

Copy .env.example to .env and set GITEA_TOKEN (and optionally PHOENIX_DEPLOY_SECRET).

Variable Default Description
PORT 4001 Listen port
GITEA_URL https://gitea.d-bis.org Gitea instance URL
GITEA_TOKEN Token for commit status API
PHOENIX_DEPLOY_SECRET Optional secret for webhook/deploy auth
PHOENIX_WEBHOOK_DEPLOY_ENABLED 0 Set to 1 to allow /webhook/gitea to execute the default target on matching pushes
PROXMOX_HOST proxmox-api.d-bis.org Proxmox host (IP or hostname) for API Railing
PROXMOX_PORT 8006 Proxmox API port
PROXMOX_USER root@pam Proxmox API user
PROXMOX_TOKEN_NAME Proxmox API token name; bare token name preferred, full token id also accepted
PROXMOX_TOKEN_VALUE Proxmox API token secret
PROXMOX_TLS_VERIFY 1 Set to 0 to allow self-signed Proxmox certs
PHOENIX_VE_LIFECYCLE_ENABLED 0 Set to 1 to enable VM/CT start/stop/reboot
PROMETHEUS_URL http://localhost:9090 Prometheus base URL for Health API
PROMETHEUS_ALERTS_URL (PROMETHEUS_URL)/api/v1/alerts Optional; use Alertmanager URL for firing alerts
PHOENIX_WEBHOOK_URL Outbound webhook URL; POST deploy events with X-Phoenix-Signature
PHOENIX_WEBHOOK_SECRET Secret to sign webhook payloads (HMAC-SHA256)
PHOENIX_PARTNER_KEYS Comma-separated API keys for /api/v1/* (optional)
PUBLIC_SECTOR_MANIFEST_PATH Override JSON path for /api/v1/public-sector/programs
PHOENIX_REPO_ROOT Proxmox repo root; loads config/public-sector-program-manifest.json if present
DEPLOY_TARGETS_PATH Override deploy target file; default is phoenix-deploy-api/deploy-targets.json

Program manifest: From a full repo checkout, the file is config/public-sector-program-manifest.json. scripts/install-systemd.sh copies it next to server.js on /opt/phoenix-deploy-api so the endpoint works without a full tree.

Gitea Webhook Configuration

In Gitea: Repository → Settings → Webhooks → Add Webhook

  • URL: https://phoenix-api-host/webhook/gitea (or your Phoenix API URL)
  • Content type: application/json
  • Events: Push events, Tag creation (and optionally Pull requests)
  • Secret: Optional, set PHOENIX_DEPLOY_SECRET to match

Use webhook-triggered deploys only for repos that are not already deploying through Gitea Actions, unless you intentionally want both paths.

Deploy API (Trigger from Gitea Actions)

curl -X POST "https://phoenix-api-host/api/deploy" \
  -H "Authorization: Bearer $PHOENIX_DEPLOY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"repo":"d-bis/proxmox","branch":"main","sha":"abc123","target":"default"}'

The API returns 404 when no matching deploy target exists for {repo, branch, target} and 500 when the target command fails. If a target defines healthcheck, the deploy is only marked successful after the post-deploy URL check passes.

Deploy target configuration

Targets live in deploy-targets.json. Each entry maps a {repo, branch, target} tuple to a command array and working directory.

Example:

{
  "repo": "d-bis/proxmox",
  "branch": "main",
  "target": "default",
  "cwd": "${PHOENIX_REPO_ROOT}",
  "command": ["bash", "scripts/deployment/deploy-phoenix-deploy-api-to-dev-vm.sh", "--apply", "--start-ct"],
  "required_env": ["PHOENIX_REPO_ROOT"]
}

Use this to promote different repos to different VMIDs or CTs by adding more entries.

Optional per-target health check:

{
  "healthcheck": {
    "url": "http://192.168.11.59:4001/health",
    "expect_status": 200,
    "expect_body_includes": "phoenix-deploy-api",
    "attempts": 8,
    "delay_ms": 3000,
    "timeout_ms": 10000
  }
}

Manual smoke trigger

From the repo root:

bash scripts/dev-vm/trigger-phoenix-deploy.sh

This calls /api/deploy directly using PHOENIX_DEPLOY_URL and PHOENIX_DEPLOY_TOKEN from root .env.

Integration with Sankofa Phoenix

This service is still standalone, but it now executes real target commands. If you later fold it into the Sankofa Phoenix API (VMID 8600), keep the same target-file pattern so repo-to-VM routing stays declarative.

OpenAPI / Swagger

  • Spec: openapi.yaml
  • HTML doc: docs/index.html — static Swagger UI; open locally or serve from phoenix-deploy-api/docs/ (loads ../openapi.yaml). To serve in-app, add swagger-ui-express and mount at e.g. /api-docs.

Run

npm install
GITEA_TOKEN=xxx npm start