Deploy Frigate NVR stack with Mosquitto, Ntfy, and frigate-notify (#190)

## Summary

Deploy a cloud-free NVR stack for the GableCam (ReoLink Elite Floodlight at 192.168.1.159):

- **Mosquitto** — shared MQTT broker in `mqtt` namespace (cluster-internal, no auth)
- **Ntfy** — self-hosted push notifications in `ntfy` namespace, exposed at `ntfy.tail8d86e.ts.net` / `ntfy.ops.eblu.me`
- **Frigate** — NVR with GableCam via HTTP-FLV, ONNX CPU detection, NFS recordings on sifaka, exposed at `nvr.tail8d86e.ts.net` / `nvr.ops.eblu.me`
- **frigate-notify** — bridges Frigate detection events (person, car, dog, cat) to Ntfy alerts via MQTT

Also includes:
- Prometheus scrape target for Frigate metrics
- Grafana dashboard for Frigate (status, inference speed, FPS, CPU/memory, storage)
- Caddy reverse proxy entries for `nvr.ops.eblu.me` and `ntfy.ops.eblu.me`

## Prerequisites

- [ ] Create NFS share `frigate` on sifaka (`/volume1/frigate`, RW for indri)
- [ ] Create 1Password item "Reolink Floodlight Camera" in `blumeops` vault with `username` and `password` fields

## Deployment (after merge)

```bash
argocd app sync apps
argocd app sync mosquitto
argocd app sync ntfy
argocd app sync frigate
argocd app sync grafana-config
argocd app sync prometheus
mise run provision-indri -- --tags caddy
mise run services-check
```

## Verification

- [ ] Mosquitto pod running, accepting connections on 1883
- [ ] Ntfy web UI accessible at `ntfy.ops.eblu.me`
- [ ] Frigate web UI at `nvr.ops.eblu.me` showing GableCam live feed
- [ ] Object detection working (ONNX, person/car/dog/cat)
- [ ] Recordings appearing in NFS share on sifaka
- [ ] frigate-notify sending detection alerts to Ntfy
- [ ] Prometheus scraping Frigate metrics
- [ ] Grafana dashboard showing Frigate data

Reviewed-on: https://forge.ops.eblu.me/eblume/blumeops/pulls/190
This commit is contained in:
Erich Blume 2026-02-14 21:27:44 -08:00
commit 04c7f3c45a
39 changed files with 1136 additions and 27 deletions

View file

@ -0,0 +1 @@
Deploy cloud-free NVR stack: Frigate 0.16.4 (ARM64) with ONNX/YOLO-NAS-s detection, Mosquitto MQTT broker, Ntfy self-hosted push notifications (with iOS APNs relay), and frigate-notify for detection alerting. GableCam (ReoLink Elite Floodlight) connected via RTSP with NFS recordings on sifaka, Grafana dashboard, Prometheus scraping, Homepage integration, and Caddy reverse proxies at nvr.ops.eblu.me and ntfy.ops.eblu.me.

View file

@ -14,3 +14,4 @@ Plans that have been fully implemented and verified. Kept for historical referen
|------|-----------|-------------|
| [[adopt-dagger-ci]] | 2026-02-11 | Adopt Dagger as CI/CD build engine (Phases 13) |
| [[segment-home-network]] | 2026-02-14 | Manual three-network segmentation for UniFi Express 7 |
| [[operationalize-reolink-camera]] | 2026-02-15 | Deploy Frigate NVR stack with Mosquitto, Ntfy, and frigate-notify |

View file

@ -11,8 +11,9 @@ tags:
# Plan: Operationalize ReoLink Camera
> **Status:** Planned (not yet executed)
> **Status:** Completed (2026-02-15)
> **Depends on:** [[add-unifi-pulumi-stack]] — the camera must be on the IoT VLAN, isolated from the rest of the network.
> **PR:** #190
## Background
@ -241,23 +242,23 @@ Camera settings to apply: enable RTSP and ONVIF, set "fluency first" encoding mo
## Verification Checklist
- [ ] Camera streams accessible via RTSP from services subnet
- [ ] Camera has no internet access (blocked at firewall)
- [ ] Frigate pod is running and showing live camera feed in web UI
- [ ] Recordings appearing in NFS share on sifaka
- [ ] Object detection working (person/vehicle detected in Frigate UI)
- [ ] Retention policy active (old recordings cleaned up automatically)
- [ ] Alerts firing on detection events
- [ ] Prometheus metrics visible in Grafana dashboard
- [ ] `mise run services-check` passes
- [x] Camera streams accessible via RTSP from services subnet
- [ ] Camera has no internet access (blocked at firewall) — pending IoT VLAN segmentation
- [x] Frigate pod is running and showing live camera feed in web UI
- [x] Recordings appearing in NFS share on sifaka
- [x] Object detection working (person/vehicle detected in Frigate UI)
- [x] Retention policy active (old recordings cleaned up automatically)
- [x] Alerts firing on detection events (ntfy push notifications with ~6s delivery)
- [x] Prometheus metrics visible in Grafana dashboard
- [x] `mise run services-check` passes
## Open Questions
## Open Questions (Resolved)
- **MQTT broker:** Is there an existing MQTT broker in the cluster, or does one need to be deployed? Mosquitto is lightweight and standard.
- **Home Assistant:** Frigate works standalone, but HA adds richer automation (e.g., turn on floodlight when person detected, arm/disarm by time of day). Evaluate whether to add HA as a future plan.
- **Sifaka NFS share sizing:** How much space to allocate on the NAS? Start with 2 TB and monitor. The hybrid retention strategy keeps this manageable.
- **Additional cameras:** If more cameras are added later, CPU detection may become a bottleneck. At that point, evaluate a Hailo-8L USB accelerator or a dedicated Frigate host (e.g., RPi5).
- **Floodlight automation:** The ReoLink HTTP API supports floodlight control. Could be automated to turn on when Frigate detects a person at night — but this requires either HA or a custom script listening to MQTT events.
- **MQTT broker:** Deployed Mosquitto (eclipse-mosquitto:2) in the `mqtt` namespace. Lightweight, anonymous access, cluster-internal only (no Caddy/ingress needed since MQTT is TCP, not HTTP).
- **Home Assistant:** Deferred. Frigate + frigate-notify + ntfy provides a complete pipeline without HA.
- **Sifaka NFS share sizing:** Allocated 2 TB. Hybrid retention (3d continuous, 30d alerts, 14d detections) keeps usage well within bounds.
- **Additional cameras:** Using ONNX/YOLO-NAS-s on CPU at ~535ms/frame, ~2 FPS detection. Adequate for single camera. Apple Silicon Detector (ASD) via ZMQ is the next upgrade path for better performance (~15ms via Neural Engine). Requires Frigate 0.17+.
- **Floodlight automation:** Deferred to future Home Assistant evaluation.
## Future Considerations