README.md · last modified 2026-05-10 16:43
Web dashboard for managing all services on soundappraisal-dev-server (Mac Mini). Built with FastAPI and HTMX.
URL: https://soundappraisal-dev-server.tail184f99.ts.net/app-manager
Port: 5014
Launchd label: com.tjeerd.saappmanager
The app manager runs as a launchd daemon and provides a web UI to start, stop, restart, and monitor all services on the Mini. It reads the service registry from ~/SA_projects/report_pipeline_2026/apps/apps_registry.toml and uses launchctl to control services.
--reload)SA_3.13All services on the Mini are managed through macOS launchd. They fall into two categories:
type = "daemon")/Library/LaunchDaemons/sudo launchctl (system domain)Current daemons:
| Service | Label | Port | Funnel path |
|---|---|---|---|
| Node Inspector (DB) | eu.soundappraisal.node-inspector |
5011 | — |
| Sound Annotator | eu.soundappraisal.sa-annotator |
5012 | /sa-annotation |
| Template Management | eu.soundappraisal.template-management |
5013 | — |
| Batch Downloader | eu.soundappraisal.batch-downloader |
— | — |
| Data Server | com.sa.data-server |
5016 | — |
| Brabantzorg MoSART | com.soundappraisal.brabantzorg |
8002 | /mosart_bz |
| Geluidmeetdag | com.soundappraisal.geluidmeetdag |
8003 | /geluidmeetdag |
| App Manager | com.tjeerd.saappmanager |
5014 | /app-manager |
| Mercouris HTTP Server | dev.soundappraisal.mercouris-httpd |
8073 | /mercouris |
| Mercouris Downloader | dev.soundappraisal.mercouris-audio |
— | — |
| PostgreSQL (T9) | dev.soundappraisal.postgresql-t9 |
5432 | — |
type = "agent")~/Library/LaunchAgents/launchctl (user domain, no sudo)Current agents:
| Service | Label | Port |
|---|---|---|
| Ollama | com.tjeerd.ollama |
11434 |
| Caddy (Ollama proxy) | com.tjeerd.caddy-ollama |
— |
| Open WebUI | com.tjeerd.open-webui |
3000 |
Each service has a plist with:
- RunAtLoad: true — starts automatically
- KeepAlive: true — restarts on crash
- UserName: tjeerd — (daemons only) runs as the tjeerd user
- StandardOutPath / StandardErrorPath — log locations
Daemon plists use sudo launchctl kickstart -k system/<label> to restart.
Agent plists use launchctl kickstart -k gui/<uid>/<label>.
Services are exposed to the internet via Tailscale Funnel on https://soundappraisal-dev-server.tail184f99.ts.net. The funnel routes are defined in the [funnel] section of apps_registry.toml and configured separately in Tailscale.
Additionally, port 8443 (tailnet only) proxies Open WebUI, and port 11443 (tailnet only) proxies Ollama.
All services are defined in a single TOML file:
~/SA_projects/report_pipeline_2026/apps/apps_registry.toml
Each [services.<id>] entry has:
- name — display name
- launchd_label — macOS launchd label
- type — "daemon" or "agent"
- port — listening port (0 for background workers)
- log_file — path to the stderr/log file
- url — web URL (if applicable)
- funnel_path — Tailscale Funnel route (if exposed)
- app_dir — (optional) path to the app directory, enables the Readme button
~/Scripts/sa_app_manager/
├── main.py # FastAPI app, routes, HTMX endpoints
├── app_runner.py # launchctl integration, status checks
├── config.py # Registry loader, dataclasses
├── start_app_manager.sh # Startup script (conda + uvicorn)
└── templates/
├── base.html # Layout and CSS
├── dashboard.html # Main dashboard
├── readme.html # README viewer page
├── overview.html # Pipeline overview page
└── partials/
├── service_row.html # Single service row
├── service_rows.html # All rows (daemons + agents)
├── log_viewer.html # Log tail panel
└── readme_viewer.html # (legacy, unused)
/Library/LaunchDaemons/ (daemon) or ~/Library/LaunchAgents/ (agent)sudo launchctl load /Library/LaunchDaemons/<label>.plist[services.<id>] entry to apps_registry.toml