diff --git a/kubernetes/apps/default/frigate/.gitkeep b/kubernetes/apps/default/frigate/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/kubernetes/apps/default/frigate/app/config/config.yml b/kubernetes/apps/default/frigate/app/config/config.yml new file mode 100644 index 000000000..4b50215f8 --- /dev/null +++ b/kubernetes/apps/default/frigate/app/config/config.yml @@ -0,0 +1,165 @@ +--- +# yaml-language-server: $schema=https://frigate.devbu.io/api/config/schema.json +logger: + default: info + # logs: + # frigate.record: debug + +mqtt: + host: emqx.default.svc.cluster.local + topic_prefix: frigate + user: "{FRIGATE_MQTT_USERNAME}" + password: "{FRIGATE_MQTT_PASSWORD}" + +database: + path: /data/frigate.db + +detectors: + coral: + type: edgetpu + device: usb + +ffmpeg: + global_args: ["-hide_banner", "-loglevel", "warning"] + hwaccel_args: ["-hwaccel", "vaapi", "-hwaccel_device", "/dev/dri/renderD128", "-hwaccel_output_format", "yuv420p"] + output_args: + record: preset-record-reolink + +snapshots: + enabled: true + timestamp: false + bounding_box: true + retain: + default: 2 + +record: + enabled: true + retain: + days: 2 + mode: all + events: + retain: + default: 2 + mode: active_objects + +objects: + track: ["person"] + filters: + person: + min_area: 5000 + max_area: 100000 + threshold: 0.7 + +# go2rtc: +# streams: +# frigate_porch_hq: rtspx://unifi-protect.turbo.ac:7441/j0GwJJkeqgWeDict +# frigate_porch_lq: rtspx://unifi-protect.turbo.ac:7441/vXHPHzP9FVRJfDuY +# frigate_driveway_hq: rtspx://unifi-protect.turbo.ac:7441/Ccg9H1IizE1vs1uY +# frigate_driveway_lq: rtspx://unifi-protect.turbo.ac:7441/yTDnSmMVDs6C8Zn2 +# frigate_garage_hq: rtspx://unifi-protect.turbo.ac:7441/m5oOVxjEFf0a7An8 +# frigate_garage_lq: rtspx://unifi-protect.turbo.ac:7441/rfX5a2wiqGcwhkkT +# frigate_river_hq: rtspx://unifi-protect.turbo.ac:7441/4TS1FINEr5tOeF7Q +# frigate_river_lq: rtspx://unifi-protect.turbo.ac:7441/LgRGGzkoV1lelHBE +# frigate_study_hq: rtspx://unifi-protect.turbo.ac:7441/SViFPpsChGahJTpR +# frigate_study_lq: rtspx://unifi-protect.turbo.ac:7441/fHV4bNS1KiYJb3nK +# frigate_living_room_hq: rtspx://unifi-protect.turbo.ac:7441/XRuGR7p9aDEg9jdB +# frigate_living_room_lq: rtspx://unifi-protect.turbo.ac:7441/7qEIbCsbYqn4SMEj +# frigate_basement_1_hq: rtspx://unifi-protect.turbo.ac:7441/0MoNwT3jxtK7jU37 +# frigate_basement_1_lq: rtspx://unifi-protect.turbo.ac:7441/M5bhAT4dLAKZfmTD + +# cameras: +# frigate_porch: +# ffmpeg: +# inputs: +# - path: rtsp://localhost:8554/frigate_porch_lq +# roles: ["detect"] +# - path: rtsp://localhost:8554/frigate_porch_hq +# roles: ["record"] +# detect: +# width: 960 +# height: 720 +# fps: 10 +# objects: +# filters: +# person: +# mask: +# - 39,445,199,427,198,263,36,228 +# - 304,218,304,408,198,434,198,262 +# - 305,411,485,382,615,393,612,335,578,321,574,233,549,118,308,209 + +# frigate_driveway: +# ffmpeg: +# inputs: +# - path: rtsp://localhost:8554/frigate_driveway_lq +# roles: ["detect"] +# - path: rtsp://localhost:8554/frigate_driveway_hq +# roles: ["record"] +# detect: +# width: 1280 +# height: 720 +# fps: 10 +# objects: +# filters: +# person: +# mask: +# - 822,204,1280,360,1280,0,0,0,0,313 + +# frigate_garage: +# ffmpeg: +# inputs: +# - path: rtsp://localhost:8554/frigate_garage_lq +# roles: ["detect"] +# - path: rtsp://localhost:8554/frigate_garage_hq +# roles: ["record"] +# detect: +# width: 1024 +# height: 576 +# fps: 10 + +# frigate_river: +# ffmpeg: +# inputs: +# - path: rtsp://localhost:8554/frigate_river_lq +# roles: ["detect"] +# - path: rtsp://localhost:8554/frigate_river_hq +# roles: ["record"] +# detect: +# width: 1280 +# height: 720 +# fps: 10 + +# frigate_study: +# ffmpeg: +# inputs: +# - path: rtsp://localhost:8554/frigate_study_lq +# roles: ["detect"] +# - path: rtsp://localhost:8554/frigate_study_hq +# roles: ["record"] +# detect: +# width: 1280 +# height: 720 +# fps: 10 + +# frigate_living_room: +# ffmpeg: +# inputs: +# - path: rtsp://localhost:8554/frigate_living_room_lq +# roles: ["detect"] +# - path: rtsp://localhost:8554/frigate_living_room_hq +# roles: ["record"] +# detect: +# width: 1024 +# height: 576 +# fps: 10 + +# frigate_basement_1: +# ffmpeg: +# inputs: +# - path: rtsp://localhost:8554/frigate_basement_1_lq +# roles: ["detect"] +# - path: rtsp://localhost:8554/frigate_basement_1_hq +# roles: ["record"] +# detect: +# width: 1280 +# height: 720 +# fps: 10 diff --git a/kubernetes/apps/default/frigate/app/externalsecret.yaml b/kubernetes/apps/default/frigate/app/externalsecret.yaml new file mode 100644 index 000000000..fc011c63d --- /dev/null +++ b/kubernetes/apps/default/frigate/app/externalsecret.yaml @@ -0,0 +1,27 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.devbu.io/external-secrets.io/externalsecret_v1beta1.json +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: frigate + namespace: default +spec: + secretStoreRef: + kind: ClusterSecretStore + name: onepassword-connect + target: + name: frigate-secret + creationPolicy: Owner + template: + engineVersion: v2 + data: + # App + # PLUS_API_KEY: "{{ .PLUS_API_KEY }}" + # Mosquitto + FRIGATE_MQTT_USERNAME: "{{ .user_1_username }}" + FRIGATE_MQTT_PASSWORD: "{{ .user_1_password }}" + dataFrom: + # - extract: + # key: frigate + - extract: + key: emqx diff --git a/kubernetes/apps/default/frigate/app/gatus.yaml b/kubernetes/apps/default/frigate/app/gatus.yaml new file mode 100644 index 000000000..3960d3786 --- /dev/null +++ b/kubernetes/apps/default/frigate/app/gatus.yaml @@ -0,0 +1,25 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: frigate-gatus-ep + namespace: default + labels: + gatus.io/enabled: "true" +data: + config.yaml: | + endpoints: + - name: frigate + group: internal + url: 192.168.8.1 + interval: 1m + ui: + hide-hostname: true + hide-url: true + dns: + query-name: frigate.${SECRET_CLUSTER_DOMAIN} + query-type: A + conditions: + - "len([BODY]) == 0" + alerts: + - type: pushover diff --git a/kubernetes/apps/default/frigate/app/helmrelease.yaml b/kubernetes/apps/default/frigate/app/helmrelease.yaml new file mode 100644 index 000000000..1054151e8 --- /dev/null +++ b/kubernetes/apps/default/frigate/app/helmrelease.yaml @@ -0,0 +1,143 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/helmrelease-helm-v2beta1.json +apiVersion: helm.toolkit.fluxcd.io/v2beta1 +kind: HelmRelease +metadata: + name: frigate + namespace: default +spec: + interval: 30m + chart: + spec: + chart: app-template + version: 1.5.1 + sourceRef: + kind: HelmRepository + name: bjw-s + namespace: flux-system + maxHistory: 2 + install: + remediation: + retries: 3 + upgrade: + cleanupOnFail: true + remediation: + retries: 3 + uninstall: + keepHistory: false + dependsOn: + - name: intel-device-plugin-gpu + namespace: kube-system + - name: emqx + namespace: default + - name: rook-ceph-cluster + namespace: rook-ceph + - name: volsync + namespace: volsync + values: + controller: + type: statefulset + annotations: + reloader.stakater.com/auto: "true" + image: + repository: ghcr.io/blakeblackshear/frigate + tag: 0.12.1 + env: + TZ: ${TIMEZONE} + LIBVA_DRIVER_NAME: i965 + envFrom: + - secretRef: + name: frigate-secret + service: + main: + ports: + http: + port: &port 5000 + rtsp: + enabled: true + port: 8554 + probes: + liveness: &probes + enabled: true + custom: true + spec: + httpGet: + path: /api/version + port: *port + initialDelaySeconds: 0 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 3 + readiness: *probes + startup: + enabled: false + ingress: + main: + enabled: true + ingressClassName: internal + hosts: + - host: &host "{{ .Release.Name }}.${SECRET_CLUSTER_DOMAIN}" + paths: + - path: / + pathType: Prefix + tls: + - hosts: + - *host + securityContext: + privileged: true + volumeClaimTemplates: + - name: config + mountPath: /data + accessMode: ReadWriteOnce + size: 5Gi + storageClass: rook-ceph-block + persistence: + config-file: + enabled: true + type: configMap + name: frigate-configmap + subPath: config.yml + mountPath: /config/config.yml + readOnly: true + config: + enabled: true + existingClaim: frigate-config + mountPath: /data + media: + enabled: true + type: nfs + server: "${LOCAL_LAN_OPENMEDIAVAULT}" + path: /export/frigate + mountPath: /export/frigate + cache: + enabled: true + type: emptyDir + medium: Memory + sizeLimit: 4Gi + mountPath: /dev/shm + usb: + enabled: true + type: hostPath + hostPath: /dev/bus/usb + hostPathType: Directory + mountPath: /dev/bus/usb + nodeSelector: + google.feature.node.kubernetes.io/coral: "true" + intel.feature.node.kubernetes.io/gpu: "true" + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: ["plex"] + topologyKey: kubernetes.io/hostname + resources: + requests: + cpu: 10m + memory: 1000Mi + gpu.intel.com/i915: "1" + limits: + memory: 6000Mi + gpu.intel.com/i915: "1" diff --git a/kubernetes/apps/default/frigate/app/kustomization.yaml b/kubernetes/apps/default/frigate/app/kustomization.yaml new file mode 100644 index 000000000..2778407d3 --- /dev/null +++ b/kubernetes/apps/default/frigate/app/kustomization.yaml @@ -0,0 +1,19 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/SchemaStore/schemastore/master/src/schemas/json/kustomization.json +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: default +resources: + - ./externalsecret.yaml + - ./gatus.yaml + - ./helmrelease.yaml + - ./volsync.yaml + - ./volume.yaml +configMapGenerator: + - name: frigate-configmap + files: + - config.yml=./config/config.yml +generatorOptions: + disableNameSuffixHash: true + annotations: + kustomize.toolkit.fluxcd.io/substitute: disabled diff --git a/kubernetes/apps/default/frigate/app/volsync.yaml b/kubernetes/apps/default/frigate/app/volsync.yaml new file mode 100644 index 000000000..d4055bea5 --- /dev/null +++ b/kubernetes/apps/default/frigate/app/volsync.yaml @@ -0,0 +1,49 @@ +--- +# yaml-language-server: $schema=https://kubernetes-schemas.devbu.io/external-secrets.io/externalsecret_v1beta1.json +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: frigate-restic + namespace: default +spec: + secretStoreRef: + kind: ClusterSecretStore + name: onepassword-connect + target: + name: frigate-restic-secret + creationPolicy: Owner + template: + engineVersion: v2 + data: + RESTIC_REPOSITORY: '{{ .REPOSITORY_TEMPLATE }}/frigate' + RESTIC_PASSWORD: '{{ .RESTIC_PASSWORD }}' + AWS_ACCESS_KEY_ID: '{{ .AWS_ACCESS_KEY_ID }}' + AWS_SECRET_ACCESS_KEY: '{{ .AWS_SECRET_ACCESS_KEY }}' + dataFrom: + - extract: + key: volsync-restic-template +--- +# yaml-language-server: $schema=https://kubernetes-schemas.devbu.io/volsync.backube/replicationsource_v1alpha1.json +apiVersion: volsync.backube/v1alpha1 +kind: ReplicationSource +metadata: + name: frigate + namespace: default +spec: + sourcePVC: frigate-config + trigger: + schedule: "0 7 * * *" + restic: + copyMethod: Snapshot + pruneIntervalDays: 7 + repository: frigate-restic-secret + cacheCapacity: 10Gi + volumeSnapshotClassName: csi-ceph-blockpool + storageClassName: rook-ceph-block + moverSecurityContext: + runAsUser: 568 + runAsGroup: 568 + fsGroup: 568 + retain: + daily: 7 + within: 3d diff --git a/kubernetes/apps/default/frigate/app/volume.yaml b/kubernetes/apps/default/frigate/app/volume.yaml new file mode 100644 index 000000000..e2f5ded17 --- /dev/null +++ b/kubernetes/apps/default/frigate/app/volume.yaml @@ -0,0 +1,17 @@ +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: frigate-config + namespace: default + labels: + app.kubernetes.io/name: &name frigate + app.kubernetes.io/instance: *name + snapshot.home.arpa/enabled: "true" +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 5Gi + storageClassName: rook-ceph-block diff --git a/kubernetes/apps/default/frigate/ks.yaml b/kubernetes/apps/default/frigate/ks.yaml new file mode 100644 index 000000000..0973a4b12 --- /dev/null +++ b/kubernetes/apps/default/frigate/ks.yaml @@ -0,0 +1,20 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/fluxcd-community/flux2-schemas/main/kustomization-kustomize-v1.json +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: cluster-apps-frigate + namespace: flux-system +spec: + dependsOn: + - name: cluster-apps-external-secrets-stores + - name: cluster-apps-node-feature-discovery-rules + path: ./kubernetes/apps/default/frigate/app + prune: true + sourceRef: + kind: GitRepository + name: home-ops-kubernetes + wait: false + interval: 30m + retryInterval: 1m + timeout: 5m diff --git a/kubernetes/apps/default/kustomization.yaml b/kubernetes/apps/default/kustomization.yaml index 945669916..2084e66b6 100644 --- a/kubernetes/apps/default/kustomization.yaml +++ b/kubernetes/apps/default/kustomization.yaml @@ -16,6 +16,7 @@ resources: - ./firefly-iii/ks.yaml - ./flood/ks.yaml - ./freshrss/ks.yaml + - ./frigate/ks.yaml - ./ghostfolio/ks.yaml - ./hajimari/ks.yaml - ./home-assistant/ks.yaml diff --git a/kubernetes/flux/vars/cluster-settings.yaml b/kubernetes/flux/vars/cluster-settings.yaml index 2e0918f9e..b4701c111 100644 --- a/kubernetes/flux/vars/cluster-settings.yaml +++ b/kubernetes/flux/vars/cluster-settings.yaml @@ -25,6 +25,7 @@ data: LOCAL_LAN_OPNSENSE: 192.168.8.1 LOCAL_LAN_TRUENAS: 192.168.9.10 LOCAL_LAN_TRUENAS_REMOTE: 10.10.0.2 + LOCAL_LAN_OPENMEDIAVAULT: 192.168.9.13 TIMEZONE: "Europe/Paris" POSTGRES_HOST: "postgres-rw.default.svc.cluster.local." POSTGRES_PORT: "5432"