# 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=`) | | 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 `). ## 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) ```bash 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`](deploy-targets.json). Each entry maps a `{repo, branch, target}` tuple to a command array and working directory. Example: ```json { "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: ```json { "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 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](openapi.yaml) - **HTML doc:** [docs/index.html](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 ```bash npm install GITEA_TOKEN=xxx npm start ```