3.7 KiB
3.7 KiB
panel-api
HTTP API wrapper around panelctl with a web UI.
Default bind: 127.0.0.1:9911
Endpoints
Health & UI
| Method | Path | Description |
|---|---|---|
| GET | / |
Web UI (served from frontend/index.html) |
| GET | /health |
Health check |
Apps — Read
| Method | Path | Description |
|---|---|---|
| GET | /apps |
List all apps |
| GET | /apps/<name> |
Show single app manifest |
| GET | /apps/<name>/routes |
Get parsed route entries |
| GET | /apps/<name>/status |
Container status (running/stopped) |
| GET | /apps/<name>/compose |
Read compose.yaml content |
| GET | /apps/<name>/logs?tail=N |
Fetch last N log lines (default 100) |
| GET | /apps/<name>/backups |
List available backups |
| GET | /apps/<name>/backups/<file> |
Download backup zip |
Apps — Write
| Method | Path | Description |
|---|---|---|
| POST | /apps/init |
Create a new app |
| POST | /apps/<name>/routes |
Update routes (hot — Caddy reloads automatically) |
| POST | /apps/<name>/deploy |
Deploy (compose up + caddy reload) |
| POST | /apps/<name>/restart |
Restart (compose down + up) |
| POST | /apps/<name>/stop |
Stop (compose down) |
| POST | /apps/<name>/render-route |
Re-render Caddy route |
| POST | /apps/<name>/compose |
Save compose.yaml content |
| POST | /apps/<name>/validate-compose |
Validate compose file |
| POST | /apps/<name>/backup |
Create volume backup (zip) |
| POST | /apps/<name>/restore |
Restore from backup |
| POST | /apps/<name>/remove |
Remove app |
Example payloads
Create app (single route)
{
"name": "whoami",
"routes": [
{"domain": "whoami.srazka.com", "upstream": "127.0.0.1:18080"}
],
"auth": true
}
Create app (multiple routes, different ports)
{
"name": "myapp",
"routes": [
{"domain": "app.srazka.com", "upstream": "127.0.0.1:18080"},
{"domain": "api.app.srazka.com", "upstream": "127.0.0.1:18081"}
],
"auth": true
}
Create app (wildcard domain)
{
"name": "wildcard",
"routes": [
{"domain": "*.srazka.com", "upstream": "127.0.0.1:18082"}
],
"auth": false
}
Note: Wildcard domains require DNS challenge configuration in Caddy.
Update routes (hot)
{
"routes": [
{"domain": "app.srazka.com", "upstream": "127.0.0.1:18080"},
{"domain": "api.srazka.com", "upstream": "127.0.0.1:18081"}
]
}
Caddy reloads automatically via the systemd path watcher. Containers stay running.
Save compose
{
"content": "services:\n app:\n image: nginx:latest\n ports:\n - '127.0.0.1:18080:80'\n"
}
Remove and keep volumes
{
"keepVolumes": true
}
Restore from backup
{
"file": "whoami-20260101-120000.zip"
}
Routes response
{
"ok": true,
"name": "myapp",
"routes": [
{"domain": "app.srazka.com", "upstream": "127.0.0.1:18080"},
{"domain": "api.srazka.com", "upstream": "127.0.0.1:18081"}
]
}
Response format
All JSON responses include an ok boolean:
{
"ok": true,
"apps": [...]
}
Error responses:
{
"ok": false,
"error": "description",
"stderr": "panelctl error output"
}
Status response
{
"ok": true,
"name": "whoami",
"running": true,
"containers": [
{
"name": "whoami-app-1",
"state": "running",
"image": "docker.io/traefik/whoami:latest"
}
]
}
Local test
curl -s http://127.0.0.1:9911/health | jq .
curl -s http://127.0.0.1:9911/apps | jq .
curl -s http://127.0.0.1:9911/apps/whoami/status | jq .
curl -s http://127.0.0.1:9911/apps/whoami/logs?tail=50 | jq .
curl -s http://127.0.0.1:9911/apps/whoami/backups | jq .