# Homelab Butler 🤵 Unified API proxy and infrastructure management for Homelab Pfannkuchen. - **Base URL:** `http://10.4.1.116:8888` - **Authentication:** `Authorization: Bearer ` - **Version:** 2.3.2 - **Interactive API documentation:** `/docs` ## Service proxy Requests are proxied as `/{service}/{backend-path}`. Butler adds each backend's authentication automatically and forwards query parameters. | Service | Backend | Authentication | |---|---|---| | `dockhand` | `10.4.1.116:3000` | Session | | `sonarr` / `sonarr1080p` | `10.2.1.100:8989/8990` | API key | | `radarr` / `radarr1080p` | `10.2.1.100:7878/7879` | API key | | `seerr` | `10.2.1.100:5055` | API key | | `outline` | `10.1.1.100:3000` | Bearer | | `n8n` | `10.4.1.113:5678` | n8n API key | | `proxmox` | `10.5.85.11:8006` | PVE API token | | `homeassistant` | `10.10.1.1:8123` | Bearer | | `grafana` | `10.1.1.111:3000` | Bearer | | `uptime` | `10.5.85.5:3001` | Web UI only; no supported REST API | | `waha` | `10.4.1.110:3500` | API key | | `forgejo` | `10.4.1.116:3001` | Bearer | | `semaphore` | `10.4.1.116:8090` | Bearer | | `fileflows` | `10.2.1.104:8268` | Local API, no additional auth | Known secret response fields such as Dockhand's `hawserToken` and `webhookSecret` are redacted before data leaves Butler. ## Operations | Endpoint | Method | Description | |---|---:|---| | `/info` | GET | Secret-free machine-readable context | | `/status` | GET | Concurrent authenticated functional probes with deterministic states | | `/overview` | GET | Compact overall verdict and ordered findings for lightweight models; `details=true` adds raw data | | `/audit` | GET | Recent proxied/management calls | | `/health/all` | GET | SSH reachability and Docker status for inventory hosts | | `/backup/status` | GET | Concurrent Borgmatic checks with age, state and summary | | `/disk/usage` | GET | Root filesystem usage per host | | `/logs/{host}/{container}` | GET | Docker logs, `tail` query supported | | `/docker/inspect/{host}/{container}` | GET | Sanitized image, runtime, resources, mounts and state | | `/docker/restart/{host}/{container}` | POST | Restart container; supports `dry_run=true` | | `/config/reload` | POST | Reload YAML configuration and credential cache | ## VM lifecycle and inventory | Endpoint | Method | Description | |---|---:|---| | `/vm/list` | GET | All VMs across the seven Proxmox nodes | | `/vm/create` | POST | VM deployment; supports `dry_run=true` | | `/vm/status/{vmid}` | GET | CPU, RAM, uptime and state | | `/vm/destroy/{vmid}` | DELETE | Full lifecycle cleanup; supports `dry_run=true` | | `/inventory/host` | POST | Create or update inventory host and host vars | | `/ansible/run` | POST | Run the standard setup for a host | Example inventory upsert: ```json {"name":"example","ip":"10.5.1.115","group":"auto","user":"sascha"} ``` Node-7 VMs default to SSH user `chris`; Proxmox nodes default to `root`. ## TTS | Endpoint | Method | Description | |---|---:|---| | `/tts/speak` | POST | Chatterbox/speaker TTS | | `/tts/voices` | GET | Available Chatterbox voices | | `/tts/health` | GET | Speaker and Chatterbox status | The speaker endpoint is `10.5.85.2:10800`; Chatterbox runs at `10.2.1.104:8004`. ## Deployment Required mounts and settings are defined in `compose.yaml`: - `.env` containing `BUTLER_TOKEN` - `/app-config/kiro/api/` as flat-file credential fallback - persistent Vaultwarden cache volume - SSH key mounted read-only at `/root/.ssh` - `butler.yaml` mounted read-only at `/data/butler.yaml` Git is the source of truth. Build/recreate the Compose service only after committing and pushing changes. ## Tests ```bash python -m pytest -q tests/test_app.py ``` Integration Compose definition: `tests/compose.integration.yaml` (binds only to `127.0.0.1:8889`). ## Changelog ### 2.3.2 — 22.07.2026 - Make Vaultwarden refresh durable: persistent named cache volume, protected runtime credentials, automatic API-key re-login and atomic cache writes. - Remove the Vaultwarden master password from the tracked sync script. - Add regression tests for cache persistence and secret handling. ### 2.3.1 — 22.07.2026 - Use a writable runtime `known_hosts` file for SSH probes with read-only SSH mounts. - Correct the Semaphore backend port from the repurposed MCP-Dockhand port to port 3010. ### 2.3.0 — 22.07.2026 - Added `/overview`, a compact schema-versioned verdict for lightweight language models. - Added explicit `healthy`, `degraded`, `auth_failed`, `misconfigured` and `offline` service states. - Service probes now use the configured backend credentials and run concurrently. - Backup checks now run with bounded concurrency and a 12-second per-host timeout. - Backup results include age and severity (`healthy` up to 30 h, `warning` up to 48 h, then `critical`). - Host and disk collection now run concurrently. - Added regression tests for classification, authentication, backup age/concurrency and overview output. ### 2.2.0 — 17.07.2026 - Restored and modernized `/info`, `/health/all`, `/backup/status`, `/disk/usage` and Docker log/restart endpoints. - Fixed stale Home Assistant, Uptime Kuma and speaker addresses. - Fixed Forgejo credential fallback by deploying the YAML-driven service config. - Correct SSH defaults for Proxmox nodes and Node-7 VMs. - Added recursive secret redaction for proxied JSON. - Forward query parameters through the generic proxy. - Added validated inventory upserts. - Added regression tests and a loopback-only integration Compose setup. ### 2.1.1 - Full VM destruction lifecycle cleanup. ### 2.1.0 - YAML service configuration, status/audit endpoints, dry-run support, Hawser token sync and SOPS automation.