Manage now connects to existing Grafana/Prometheus/Alertmanager instances
and never deploys its own stack.
- docker-compose.yml / docker-compose.dev.yml: removed prometheus, loki,
alloy, grafana, alertmanager, node-exporter services, the monitoring
network, and observability named volumes; they now ship only backend +
frontend. Dev frontend now joins the web network so the Vite dev proxy
can reach the backend.
- backend: alertmanager_url default is now empty; /api/monitoring/alerts
and /alertmanager-status return graceful "not configured" responses
when ALERTMANAGER_URL is unset. Added not-configured tests.
- docker-compose.observability.yml: kept as the optional standalone
example; header clarifies Manage does not deploy it.
- Removed orphaned combined monitoring/prometheus/prometheus.yml
(standalone stack uses prometheus.standalone.yml).
- Docs (README, REQUIREMENTS decision log, monitoring-logging-design,
observability-runbooks, context.md, MIGRATION_PLAN, frontend/README,
CHANGELOG) updated to the connect-to-existing model.
VITE_GRAFANA_URL / VITE_PROMETHEUS_URL remain as optional frontend
deep-link overrides. .env.example still needs a manual update (safety
policy blocks assistant edits): set ALERTMANAGER_URL empty/optional and
move standalone-only vars out of the root file.
PR 4a of the runtime service registry change.
- Remove addon pages (/addons/:addonId, AddonPage, addons/*) superseded by
service pages.
- Remove grafana_url/prometheus_url from backend config, compose, .env.example,
and README (URLs now live on service records; VITE_ frontend deep-link vars
retained).
- Add Services page (/services) with create/list/delete + sidebar nav, so
services are configurable in the tool itself and service pages are reachable.
- Update docs/REQUIREMENTS.md service-registry section; add CHANGELOG.md with
the breaking-upgrade note (MANAGE_ENCRYPTION_KEY required; grafana/prometheus
env vars removed; default widget seeding removed).
Verification: backend ruff clean, pytest 222 passed; frontend lint 0 errors,
build success, 70 tests passed.
The 2026-06-16/17 observability update externalised metrics to
Prometheus + node_exporter + Grafana, but the legacy Manage-side
SSH-scraping monitor was never removed. It duplicated the new stack,
ran SSH df on every machine every 300s, and fed nothing (its UI was
deleted in e2ad731). This slice decommissions the duplication.
Removed (backend):
- services/monitoring_poller.py (MonitoringPoller) — entire file
- services/monitoring_actions.py (disk_space, run_machine_operation,
poll_machine_snapshot, build_machine_client) — entire file;
run_machine_operation had only 2 callers (the poller + /disk), both gone
- tests/test_monitoring_actions.py
- endpoints: POST /api/monitoring/poller, GET /machines/{id}/actions,
GET /disk (and the now-dead _resolve_machine helper)
- lifespan wiring (main.py), dependency wrapper (dependencies.py),
poller.start()/kick() from machine save (routers/settings.py)
- SettingsStore: monitoring_machine_actions table CREATE + 2 indexes +
record/list/prune_machine_actions methods; DROP TABLE IF EXISTS on
startup cleans existing DBs (user-approved)
- config knobs: monitoring_poll_interval_seconds,
monitoring_poll_initial_delay_seconds, monitoring_action_retention_days
- test_api.py: TestMonitoring._ensure_machine + test_disk
Kept (fits the new model): /machines, /prometheus-targets, /alerts,
/alertmanager-status, /alertmanager-webhook; the disk_usage JOB template
(manual on-demand, not monitoring); node_exporter_* machine fields
(they point Prometheus at the right host).
Gate: backend pytest 173 passed; ruff clean.
- backend/ uses proper Python src layout (src/media_library_viewer_api/)
with pyproject.toml, hatchling build, and PYTHONPATH=src convention
- frontend/ is a Vite + React + TypeScript SPA
- archive/ preserves the original Streamlit prototype for reference
- Cleaned up root to only contain docs, license, and subproject dirs
- Updated README for the new dual-subproject architecture