Post

Frigate - Open Source NVR With Real-Time AI Object Detection

Frigate - Open Source NVR With Real-Time AI Object Detection

Frigate - CCTV is an open source NVR built around real-time AI object detection. All processing is performed locally on your own hardware, and your camera feeds never leave your home.

Frigate is configured to save media to /media/frigate which is a CIFS mount to my Unraid Server.

It use GPU acceleration via the integrated graphics on the processor and uses Open VINO for the AI detection.

Since this uses media from my NAS i have simply decided to run this as a Docker Container on UnRAID on my NAS instead of having it as part of my kubernetes cluster to remove the need to access the NAS media remotely

Kubernetes Manifest

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: frigate
    app.kubernetes.io/instance: frigate
    app.kubernetes.io/name: frigate
  name: frigate
  namespace: frigate
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: frigate
  template:
    metadata:
      labels:
        app: frigate
        app.kubernetes.io/name: frigate
    spec:
      nodeSelector:
        nas: "true"
      containers:
      - image: ghcr.io/blakeblackshear/frigate:stable
        name: frigate
        ports:
          - containerPort: 5000
            hostPort: 5000
            protocol: TCP
          - containerPort: 8554
            hostPort: 8554
            protocol: TCP
        env:
        - name: TZ
          value: Europe/London
        volumeMounts:
        - mountPath: "/media"
          readOnly: false
          name: smb
        - mountPath: "/db"
          readOnly: false
          name: db
        - mountPath: /config/config.yml
          name: frigate-config
          subPath: config.yml
        - mountPath: /dev/dri
          name: dri
        securityContext:
          privileged: true
      volumes:
        - name: smb
          persistentVolumeClaim:
            claimName: pvc-frigate-smb
        - name: frigate-config
          configMap:
            name: frigate-config
        - name: db
          persistentVolumeClaim:
            claimName: frigate
        - name: dri
          hostPath:
            path: /dev/dri
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: frigate
  name: frigate
  namespace: frigate 
spec:
  type: LoadBalancer
  loadBalancerIP: 10.0.10.210
  ports:
  - name: web-tcp
    port: 5000
    protocol: TCP
    targetPort: 5000
  selector:
    app: frigate
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: frigate
  namespace: frigate
  annotations: 
    kubernetes.io/ingress.class: traefik-external
    gethomepage.dev/href: "https://cctv.f9.casa"
    gethomepage.dev/enabled: "true"
    gethomepage.dev/description: CCTV Management
    gethomepage.dev/group: Home Automation
    gethomepage.dev/icon: frigate.png
    gethomepage.dev/name: Frigate
    gethomepage.dev/weight: "10000"
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`cctv.f9.casa`)
      kind: Rule
      services:
        - name: frigate
          port: 5000
      middlewares:
        - name: default-headers
          namespace: default
        - name: authentik
          namespace: authentik
  tls:
    secretName: f9-casa-tls

Docker Compose

Note that as I use Docker Swarm I am making use of https://github.com/allfro/device-mapping-manager to pass through dev’s to swarm containers by faking a volume, this container then detects that fake volume and maps it as a device

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
version: '3.9'
services:
  frigate:
    image: ghcr.io/blakeblackshear/frigate:stable
    hostname: frigate
    privileged: true
    networks:
      - traefik-public
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /srv/cephfs/docker/appdata/frigate/db:/db
      - /srv/cephfs/docker/appdata/frigate/config.yml:/config/config.yml
      - /srv/cctv:/media/frigate
      - /dev/dri:/dev/dri
    ports:
        - "5000:5000"
        - "8554:8554"
    deploy:
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.frigate.rule=Host(`cctv.f9.casa`)"
        - "traefik.http.services.frigate.loadbalancer.server.port=5000"
        - "traefik.http.routers.frigate.entrypoints=https"
        - "traefik.http.routers.frigate.tls=true"
        - "traefik.http.routers.frigate.tls.certresolver=letsencrypt"

        - "traefik.http.routers.frigate.middlewares=authentik@docker"

        - homepage.group=Home Automation
        - homepage.name=Frigate
        - homepage.icon=frigate.png
        - homepage.href=https://cctv.f9.casa
        - homepage.description=CCTV Management
        - homepage.siteMonitor=http://frigate:5000
        - homepage.weight=10000
      mode: replicated
      placement:
        constraints:
          - node.labels.gpu == true
networks:
  traefik-public:
    external: true

Configuration

config.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
database:
  path: /db/frigate.db

mqtt: # If you have a MQTT server then update this section, if not delete it.
  host: 10.0.0.1
  user: [REDACTED]
  password: [REDACTED]

birdseye:
  enabled: false

ffmpeg:
  hwaccel_args: preset-vaapi

objects: # Object to detect - https://docs.frigate.video/configuration/objects
  track:
  - person

record: # what you want Frigate to record
  enabled: true
  retain:
    mode: motion
    days: 30
  events:
    retain:
      default: 14
      mode: active_objects

snapshots:
  enabled: true
  retain:
    default: 30

go2rtc:
  streams:
    home_stream:
    - rtsp://[REDACTED]:554/Streaming/Channels/101   
    home_stream_sub:
    - rtsp://[REDACTED]:554/Streaming/Channels/102

cameras:
  Home:
    ffmpeg:
      inputs:
      - path: rtsp://127.0.0.1:8554/home_stream
        input_args: preset-rtsp-restream
        roles:
        - record
      - path: rtsp://127.0.0.1:8554/home_stream_sub
      	input_args: preset-rtsp-restream
        roles:
        - detect
    motion:
      mask:
      - 640,320,589,360,640,360,640,154,458,145
      - 214,328,212,348,22,347,24,328
    zones:
      garden:
        coordinates: 0,360,589,360,452,216,0,205
      public:
        coordinates: 640,0,640,188,0,152,0,0
This post is licensed under CC BY 4.0 by the author.