From bc57edc1a4733375bc42d1f6765e23a821cf5e70 Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Thu, 19 Feb 2026 10:54:22 -0800 Subject: [PATCH] Port Mosquitto and ntfy to ringtail k3s, retire Apple Silicon Detector MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move MQTT broker and push notification services from indri minikube to ringtail k3s cluster. Delete the frigate_detector ansible role — detection will use ringtail's RTX 4080 when Frigate is ported. Manual cleanup needed on indri: ssh indri 'launchctl unload ~/Library/LaunchAgents/mcquack.eblume.frigate-detector.plist' ssh indri 'rm ~/Library/LaunchAgents/mcquack.eblume.frigate-detector.plist' Co-Authored-By: Claude Opus 4.6 --- ansible/playbooks/indri.yml | 2 - .../roles/frigate_detector/defaults/main.yml | 8 --- .../roles/frigate_detector/handlers/main.yml | 6 -- ansible/roles/frigate_detector/tasks/main.yml | 55 ------------------- .../mcquack.eblume.frigate-detector.plist.j2 | 43 --------------- ...mosquitto.yaml => mosquitto-ringtail.yaml} | 4 +- argocd/apps/{ntfy.yaml => ntfy-ringtail.yaml} | 4 +- .../feature-port-mqtt-ntfy-ringtail.infra.md | 1 + docs/reference/services/frigate.md | 8 +-- 9 files changed, 8 insertions(+), 123 deletions(-) delete mode 100644 ansible/roles/frigate_detector/defaults/main.yml delete mode 100644 ansible/roles/frigate_detector/handlers/main.yml delete mode 100644 ansible/roles/frigate_detector/tasks/main.yml delete mode 100644 ansible/roles/frigate_detector/templates/mcquack.eblume.frigate-detector.plist.j2 rename argocd/apps/{mosquitto.yaml => mosquitto-ringtail.yaml} (81%) rename argocd/apps/{ntfy.yaml => ntfy-ringtail.yaml} (82%) create mode 100644 docs/changelog.d/feature-port-mqtt-ntfy-ringtail.infra.md diff --git a/ansible/playbooks/indri.yml b/ansible/playbooks/indri.yml index f1c7d11..3042366 100644 --- a/ansible/playbooks/indri.yml +++ b/ansible/playbooks/indri.yml @@ -175,5 +175,3 @@ tags: jellyfin_metrics - role: caddy tags: caddy - - role: frigate_detector - tags: frigate_detector diff --git a/ansible/roles/frigate_detector/defaults/main.yml b/ansible/roles/frigate_detector/defaults/main.yml deleted file mode 100644 index 71af21d..0000000 --- a/ansible/roles/frigate_detector/defaults/main.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -frigate_detector_repo: https://forge.ops.eblu.me/eblume/apple-silicon-detector.git -frigate_detector_dir: "{{ ansible_env.HOME }}/code/3rd/apple-silicon-detector" -frigate_detector_endpoint: "tcp://*:5555" -frigate_detector_model: AUTO -frigate_detector_log_dir: "{{ ansible_env.HOME }}/Library/Logs" -frigate_detector_uv_binary: "{{ ansible_env.HOME }}/.local/share/mise/installs/uv/latest/uv-aarch64-apple-darwin/uv" -frigate_detector_python: "3.12" diff --git a/ansible/roles/frigate_detector/handlers/main.yml b/ansible/roles/frigate_detector/handlers/main.yml deleted file mode 100644 index 850c66c..0000000 --- a/ansible/roles/frigate_detector/handlers/main.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -- name: Restart frigate-detector - ansible.builtin.shell: | - launchctl unload ~/Library/LaunchAgents/mcquack.eblume.frigate-detector.plist 2>/dev/null || true - launchctl load ~/Library/LaunchAgents/mcquack.eblume.frigate-detector.plist - changed_when: true diff --git a/ansible/roles/frigate_detector/tasks/main.yml b/ansible/roles/frigate_detector/tasks/main.yml deleted file mode 100644 index 07b5ffc..0000000 --- a/ansible/roles/frigate_detector/tasks/main.yml +++ /dev/null @@ -1,55 +0,0 @@ ---- -# Apple Silicon ZMQ detector for Frigate -# Runs natively on macOS, using CoreML / Neural Engine for ~15ms inference. -# Communicates with Frigate via ZMQ over TCP. -# Dependencies managed inline by uv — no venv or make install needed. -# -# ONE-TIME SETUP (before running ansible): -# -# 1. Clone the repo (use localhost:3001 - hairpinning doesn't work): -# ssh indri 'git clone http://localhost:3001/eblume/apple-silicon-detector.git ~/code/3rd/apple-silicon-detector' -# -# 2. Run ansible to deploy LaunchAgent: -# mise run provision-indri -- --tags frigate_detector - -- name: Verify apple-silicon-detector repo exists - ansible.builtin.stat: - path: "{{ frigate_detector_dir }}/detector/zmq_onnx_client.py" - register: frigate_detector_stat - -- name: Fail if apple-silicon-detector not found - ansible.builtin.fail: - msg: | - apple-silicon-detector not found at {{ frigate_detector_dir }}. - Please clone first: - ssh indri 'git clone {{ frigate_detector_repo }} {{ frigate_detector_dir }}' - when: not frigate_detector_stat.stat.exists - -- name: Verify uv binary exists - ansible.builtin.stat: - path: "{{ frigate_detector_uv_binary }}" - register: frigate_detector_uv_stat - -- name: Fail if uv not found - ansible.builtin.fail: - msg: "uv not found at {{ frigate_detector_uv_binary }}. Install via mise: mise use uv@latest" - when: not frigate_detector_uv_stat.stat.exists - -- name: Deploy frigate-detector LaunchAgent plist - ansible.builtin.template: - src: mcquack.eblume.frigate-detector.plist.j2 - dest: ~/Library/LaunchAgents/mcquack.eblume.frigate-detector.plist - mode: '0644' - notify: Restart frigate-detector - -- name: Check if frigate-detector LaunchAgent is loaded - ansible.builtin.command: launchctl list mcquack.eblume.frigate-detector - register: frigate_detector_launchctl_check - changed_when: false - failed_when: false - -- name: Load frigate-detector LaunchAgent if not loaded - ansible.builtin.command: launchctl load ~/Library/LaunchAgents/mcquack.eblume.frigate-detector.plist - when: frigate_detector_launchctl_check.rc != 0 - changed_when: true - failed_when: false diff --git a/ansible/roles/frigate_detector/templates/mcquack.eblume.frigate-detector.plist.j2 b/ansible/roles/frigate_detector/templates/mcquack.eblume.frigate-detector.plist.j2 deleted file mode 100644 index 87921ac..0000000 --- a/ansible/roles/frigate_detector/templates/mcquack.eblume.frigate-detector.plist.j2 +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - Label - mcquack.eblume.frigate-detector - ProgramArguments - - {{ frigate_detector_uv_binary }} - run - --python - {{ frigate_detector_python }} - --with - numpy==1.26.* - --with - opencv-python-headless==4.11.0.* - --with - opencv-contrib-python==4.11.0.* - --with - onnxruntime==1.22.* - --with - pyzmq==26.2.* - --with - pydantic==2.10.* - detector/zmq_onnx_client.py - --model - {{ frigate_detector_model }} - --endpoint - {{ frigate_detector_endpoint }} - - WorkingDirectory - {{ frigate_detector_dir }} - RunAtLoad - - KeepAlive - - StandardOutPath - {{ frigate_detector_log_dir }}/mcquack.frigate-detector.out.log - StandardErrorPath - {{ frigate_detector_log_dir }}/mcquack.frigate-detector.err.log - - diff --git a/argocd/apps/mosquitto.yaml b/argocd/apps/mosquitto-ringtail.yaml similarity index 81% rename from argocd/apps/mosquitto.yaml rename to argocd/apps/mosquitto-ringtail.yaml index 976dd5c..e5fc92f 100644 --- a/argocd/apps/mosquitto.yaml +++ b/argocd/apps/mosquitto-ringtail.yaml @@ -2,7 +2,7 @@ apiVersion: argoproj.io/v1alpha1 kind: Application metadata: - name: mosquitto + name: mosquitto-ringtail namespace: argocd spec: project: default @@ -11,7 +11,7 @@ spec: targetRevision: main path: argocd/manifests/mosquitto destination: - server: https://kubernetes.default.svc + server: https://ringtail.tail8d86e.ts.net:6443 namespace: mqtt syncPolicy: syncOptions: diff --git a/argocd/apps/ntfy.yaml b/argocd/apps/ntfy-ringtail.yaml similarity index 82% rename from argocd/apps/ntfy.yaml rename to argocd/apps/ntfy-ringtail.yaml index 8846b7f..65b10f7 100644 --- a/argocd/apps/ntfy.yaml +++ b/argocd/apps/ntfy-ringtail.yaml @@ -2,7 +2,7 @@ apiVersion: argoproj.io/v1alpha1 kind: Application metadata: - name: ntfy + name: ntfy-ringtail namespace: argocd spec: project: default @@ -11,7 +11,7 @@ spec: targetRevision: main path: argocd/manifests/ntfy destination: - server: https://kubernetes.default.svc + server: https://ringtail.tail8d86e.ts.net:6443 namespace: ntfy syncPolicy: syncOptions: diff --git a/docs/changelog.d/feature-port-mqtt-ntfy-ringtail.infra.md b/docs/changelog.d/feature-port-mqtt-ntfy-ringtail.infra.md new file mode 100644 index 0000000..f58dac9 --- /dev/null +++ b/docs/changelog.d/feature-port-mqtt-ntfy-ringtail.infra.md @@ -0,0 +1 @@ +Port Mosquitto (MQTT) and ntfy to ringtail k3s; retire Apple Silicon Detector from indri. diff --git a/docs/reference/services/frigate.md b/docs/reference/services/frigate.md index edd93af..0e661fe 100644 --- a/docs/reference/services/frigate.md +++ b/docs/reference/services/frigate.md @@ -27,12 +27,10 @@ Open-source network video recorder (NVR) with object detection. Runs cloud-free ReoLink Camera (GableCam) │ RTSP ▼ -Frigate pod (minikube) +Frigate pod (ringtail k3s) ├── go2rtc — RTSP restream proxy ├── FFmpeg — stream decoding - ├── ZMQ detector ──tcp://host.minikube.internal:5555──→ apple-silicon-detector - │ ├── CoreML / Neural Engine - │ └── LaunchAgent (mcquack.eblume.frigate-detector) + ├── detector — GPU-accelerated (RTX 4080, pending migration) ├── /media/frigate — NFS recordings (sifaka) └── /db — SQLite (local PVC) │ @@ -49,7 +47,7 @@ Camera credentials are stored in 1Password and synced via [[external-secrets]] t ## Detection -Object detection uses the [apple-silicon-detector](https://github.com/frigate-nvr/apple-silicon-detector) with a YOLOv9-m model (`yolo-generic`, 320x320), running natively on [[indri]] as a LaunchAgent (`mcquack.eblume.frigate-detector`). It communicates with Frigate via ZMQ over TCP (`tcp://host.minikube.internal:5555`), using CoreML with partial Neural Engine acceleration (~100-170ms inference). Model ONNX files are stored on the NFS volume at `/media/frigate/models/`. +Object detection will use GPU-accelerated inference on [[ringtail]]'s RTX 4080 (migration pending). The previous Apple Silicon Detector on [[indri]] has been retired. Two zones are configured: `driveway_entrance` (triggers review alerts for person/car) and `driveway` (triggers review detections).