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/mqtt.yaml similarity index 84% rename from argocd/apps/mosquitto.yaml rename to argocd/apps/mqtt.yaml index 976dd5c..61959aa 100644 --- a/argocd/apps/mosquitto.yaml +++ b/argocd/apps/mqtt.yaml @@ -2,7 +2,7 @@ apiVersion: argoproj.io/v1alpha1 kind: Application metadata: - name: mosquitto + name: mqtt 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.yaml index 8846b7f..13927bc 100644 --- a/argocd/apps/ntfy.yaml +++ b/argocd/apps/ntfy.yaml @@ -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/argocd/manifests/ntfy/deployment.yaml b/argocd/manifests/ntfy/deployment.yaml index 7bff658..8515950 100644 --- a/argocd/manifests/ntfy/deployment.yaml +++ b/argocd/manifests/ntfy/deployment.yaml @@ -16,7 +16,7 @@ spec: spec: containers: - name: ntfy - image: registry.ops.eblu.me/blumeops/ntfy:v1.0.0 + image: registry.ops.eblu.me/blumeops/ntfy:v1.1.0-nix args: ["serve", "--config", "/etc/ntfy/server.yml"] ports: - containerPort: 80 diff --git a/containers/ntfy/default.nix b/containers/ntfy/default.nix new file mode 100644 index 0000000..47a43ab --- /dev/null +++ b/containers/ntfy/default.nix @@ -0,0 +1,27 @@ +# Nix-built ntfy push notification server +# Replaces the multi-stage Dockerfile (Node + Go + Alpine) with nixpkgs ntfy-sh +# Built with dockerTools.buildLayeredImage for efficient layer caching +{ pkgs ? import { } }: + +pkgs.dockerTools.buildLayeredImage { + name = "blumeops/ntfy"; + tag = "latest"; + + contents = [ + pkgs.ntfy-sh + pkgs.cacert + pkgs.tzdata + ]; + + config = { + Entrypoint = [ "${pkgs.ntfy-sh}/bin/ntfy" ]; + Env = [ + "SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" + "TZDIR=${pkgs.tzdata}/share/zoneinfo" + ]; + ExposedPorts = { + "80/tcp" = { }; + }; + User = "65534"; + }; +} 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).