nixos/panel/API.md
2026-05-20 01:07:37 +02:00

201 lines
4.4 KiB
Markdown

# 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)
```json
{
"name": "whoami",
"routes": [
{"domain": "whoami.srazka.com", "upstream": "127.0.0.1:18080"}
],
"auth": true
}
```
### Create app (multiple routes, different ports)
```json
{
"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 (multiple routes, different ports, with paths)
```json
{
"name": "pocketbase",
"routes": [
{"domain": "pb.srazka.com", "upstream": "127.0.0.1:8090", "path": "/_/*"}
],
"auth": true
}
```
The `path` field is optional. When present, it generates a Caddy `reverse_proxy /_/* 127.0.0.1:8090` rule, letting you route requests to a specific path prefix within a domain.
### Create app (wildcard domain)
```json
{
"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)
```json
{
"routes": [
{"domain": "app.srazka.com", "upstream": "127.0.0.1:18080"},
{"domain": "api.srazka.com", "upstream": "127.0.0.1:18081"},
{"domain": "pb.srazka.com", "upstream": "127.0.0.1:8090", "path": "/_/*"}
]
}
```
The optional `path` field generates a Caddy `reverse_proxy <path> <upstream>` rule for sub-path routing.
Caddy reloads automatically via the systemd path watcher. Containers stay running.
### Save compose
```json
{
"content": "services:\n app:\n image: nginx:latest\n ports:\n - '127.0.0.1:18080:80'\n"
}
```
### Remove and keep volumes
```json
{
"keepVolumes": true
}
```
### Restore from backup
```json
{
"file": "whoami-20260101-120000.zip"
}
```
## Routes response
```json
{
"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", "path": "/api/*"}
]
}
```
The `path` field is only present when a route has a path configured.
## Response format
All JSON responses include an `ok` boolean:
```json
{
"ok": true,
"apps": [...]
}
```
Error responses:
```json
{
"ok": false,
"error": "description",
"stderr": "panelctl error output"
}
```
## Status response
```json
{
"ok": true,
"name": "whoami",
"running": true,
"containers": [
{
"name": "whoami-app-1",
"state": "running",
"image": "docker.io/traefik/whoami:latest"
}
]
}
```
## Local test
```bash
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 .
```