Add docker-compose.observability.yml to run Grafana, Prometheus, Loki, Alertmanager, Alloy and Node Exporter independently of Manage. Includes a standalone Prometheus config, empty file-SD placeholder, and runbook documentation.
6.9 KiB
Observability Runbooks
Operational playbooks for the Manage self-hosted observability stack (Prometheus, Grafana, Loki, Alertmanager).
Service Overview
| Service | Compose name | Internal URL | Health check |
|---|---|---|---|
| Prometheus | prometheus |
http://prometheus:9090 |
/-/healthy |
| Grafana | grafana |
http://grafana:3000 |
/api/health |
| Loki | loki |
http://loki:3100 |
/ready |
| Alloy | alloy |
http://alloy:12345 |
/-/healthy |
| Alertmanager | alertmanager |
http://alertmanager:9093 |
/-/healthy |
| Node Exporter | node-exporter |
http://node-exporter:9100 |
/ |
| Manage backend | backend |
http://backend:8000 |
/api/health |
Alert: BackupJobFailed
Severity: critical
Meaning: A backup job reported status=failed within the last hour.
Steps
- Open Manage → Backups and identify the failed job/run.
- Check the run output / logs for the failure reason.
- Search Loki for
{container="backend"} | json | message=~"(?i)backup"around the failure time. - If transient (network, lock file), retry the job.
- If persistent, open a task to fix the backup script or credentials.
Alert: BackupJobStuck
Severity: warning
Meaning: No successful backup run has been recorded for a job in the last 24 hours.
Steps
- Confirm the job is still scheduled and expected to run.
- Check whether the backup scheduler/host is running.
- Verify the job can still report success to
POST /api/backups/reports. - Inspect Prometheus graph for
manage_backup_runs_last_success_timestampbyjob_name. - If the job was intentionally retired, remove or disable its reporting.
Alert: PrometheusTargetMissing
Severity: warning
Meaning: A Prometheus scrape target is down (up == 0) for more than 2 minutes.
Steps
- Identify
jobandinstancefrom the alert labels. - Check the container/process status:
docker compose ps <service>docker compose logs --tail 100 <service>
- Verify network reachability from the Prometheus container:
docker compose exec prometheus wget -qO- http://<instance>/
- If the target is a remote Node Exporter:
- Check the machine is reachable over SSH.
- Verify Node Exporter is installed and running (
systemctl status node_exporter). - Confirm the scrape host/port in Manage → Settings for that machine.
- Restart if needed:
docker compose restart <service>.
Alert: AlertmanagerDown
Severity: critical
Meaning: Prometheus cannot scrape Alertmanager; new alerts may not be delivered.
Steps
- Check container status:
docker compose ps alertmanager - Review logs:
docker compose logs --tail 200 alertmanager - Validate config syntax:
docker compose exec alertmanager amtool check-config /etc/alertmanager/alertmanager.yml
- Verify SMTP environment variables are present if using email receivers.
- Restart:
docker compose restart alertmanager
Alert: GrafanaDown
Severity: warning
Meaning: Grafana is unreachable; dashboards and iframe panels in Manage are unavailable.
Steps
- Check container status and logs.
- Verify the OAuth client configuration is correct (
GF_AUTH_GENERIC_OAUTH_*). - If embedded panels are blank, confirm Grafana
allow_embedding = trueand cookie settings. - Restart:
docker compose restart grafana
Routine Maintenance
Check overall health
cd /path/to/manage
docker compose ps
docker compose exec prometheus wget -qO- http://127.0.0.1:9090/-/healthy
docker compose exec grafana wget -qO- http://127.0.0.1:3000/api/health
docker compose exec loki wget -qO- http://127.0.0.1:3100/ready
docker compose exec alertmanager wget -qO- http://127.0.0.1:9093/-/healthy
Reload Prometheus after rule/config changes
Prometheus is started with --web.enable-lifecycle, so a SIGHUP or HTTP call reloads config:
curl -X POST http://localhost:9090/-/reload
Inspect logs
# All backend logs in Loki via Grafana Explore, or locally:
docker compose logs --tail 500 backend
# Specific service:
docker compose logs -f prometheus
Storage usage
docker system df -v
docker compose exec prometheus du -sh /prometheus
docker compose exec loki du -sh /loki
docker compose exec grafana du -sh /var/lib/grafana
Backup and Disaster Recovery
The observability data lives in named volumes:
prometheus_dataloki_datagrafana_dataalertmanager_data
Backup volumes
# Stop the stack to ensure consistency
docker compose down
# Back up each volume to a tarball
docker run --rm -v manage_prometheus_data:/data -v $(pwd)/backups:/backups alpine \
tar czf /backups/prometheus-$(date +%F).tar.gz -C /data .
docker run --rm -v manage_loki_data:/data -v $(pwd)/backups:/backups alpine \
tar czf /backups/loki-$(date +%F).tar.gz -C /data .
docker run --rm -v manage_grafana_data:/data -v $(pwd)/backups:/backups alpine \
tar czf /backups/grafana-$(date +%F).tar.gz -C /data .
docker run --rm -v manage_alertmanager_data:/data -v $(pwd)/backups:/backups alpine \
tar czf /backups/alertmanager-$(date +%F).tar.gz -C /data .
# Start the stack again
docker compose up -d
Replace
manage_with your actual Docker Compose project name if different.
Restore a volume
docker compose down
docker volume rm manage_prometheus_data
docker volume create manage_prometheus_data
docker run --rm -v manage_prometheus_data:/data -v $(pwd)/backups:/backups alpine \
tar xzf /backups/prometheus-YYYY-MM-DD.tar.gz -C /data
docker compose up -d
Standalone Observability Stack
You can run the observability services on their own without the Manage backend or frontend:
cd /path/to/manage
docker compose -f docker-compose.observability.yml up -d
This starts Prometheus, Grafana, Loki, Alertmanager, Alloy and Node Exporter. Exposed ports:
| Service | URL |
|---|---|
| Grafana | http://localhost:3000 |
| Prometheus | http://localhost:9090 |
| Alertmanager | http://localhost:9093 |
| Loki | http://localhost:3100 |
| Node Exporter | http://localhost:9100 |
| Alloy | http://localhost:12345 |
Grafana defaults to admin / admin. Datasources and dashboards are provisioned automatically.
To scrape a Manage backend from this standalone stack, edit monitoring/prometheus/prometheus.standalone.yml and add a static target for the backend's /metrics endpoint, or drop a file-SD JSON file into monitoring/prometheus/file-sd/.
Scaling Notes
- The current
deploy.resourcesblocks are tuned for a small homelab. Raise memory limits if you monitor many machines or retain logs longer than 30 days. - Loki is configured for single-node filesystem storage. For larger deployments, migrate to object storage (S3/GCS/MinIO) and a shared index.
- Prometheus remote-write or Thanos/Cortex can be added later for long-term metrics without changing application instrumentation.