- 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
136 lines
6.0 KiB
Markdown
136 lines
6.0 KiB
Markdown
# 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)
|
|
|
|
```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
|
|
```
|