Encourage FUNIX

The consultation of the site is completely free and without advertisements. Donations are nevertheless appreciated to pay for hosting and encourage its author


CCTV systems - Frigate overview

CCTV systems

Presentation of Frigate

October 30, 2025


Presentation

This section aims to introduce you to various tools for setting up a Linux-based video surveillance system using independent surveillance cameras (IP or Wi-Fi), analog, digital, or simple webcams, also known as CCTV. ZoneMinder and Frigate are presented here. They all allow you to integrate a wide range of cameras, perform automatic motion detection, and create events. They are also web-based, allowing you to configure them, view the cameras in real time, and manage events via a browser, whether on a desktop or mobile device. ZoneMinder and Frigate are advanced tools with  machine learning and object recognition capabilities. ZoneMinder can also be considered more complex than Frigate, which integrates with Home Assistant.
This section is divided into several pages:

Docker and Frigate Installation

Frigate relies on Docker , which I installed simply by typing on my Mageia.

urpmi docker docker-compose

Next, we launch Docker by typing

systemctl start docker

that is its status

systemctl status docker

and the result

docker.service - Docker Application Container Engine
     Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; preset: disabled)
     Active: active (running) since Fri 2025-09-26 17:02:55 CEST; 6s ago
       Docs: http://docs.docker.com
    Process: 210883 ExecStartPre=/usr/sbin/docker-network-cleanup (code=exited, status=0/SUCCESS)
   Main PID: 210886 (dockerd)
      Tasks: 17
     Memory: 41.1M
        CPU: 369ms
     CGroup: /system.slice/docker.service
             ├─210886 /usr/sbin/dockerd --data-root /var/cache/docker -H unix:///var/run/docker.sock -H tcp://127.0.0.1:2375
             └─210899 containerd --config /var/run/docker/containerd/containerd.toml

sept. 26 17:02:52 ultra.kervao.fr dockerd[210899]: time="2025-09-26T17:02:52.687489959+02:00" level=info msg=serving... address=/var/run/docker/containerd/containerd.sock
sept. 26 17:02:52 ultra.kervao.fr dockerd[210899]: time="2025-09-26T17:02:52.687576078+02:00" level=info msg="containerd successfully booted in 0.201550s"
sept. 26 17:02:54 ultra.kervao.fr dockerd[210886]: time="2025-09-26T17:02:54.283134739+02:00" level=info msg="Loading containers: start."
sept. 26 17:02:55 ultra.kervao.fr dockerd[210886]: time="2025-09-26T17:02:55.007460149+02:00" level=info msg="Loading containers: done."
sept. 26 17:02:55 ultra.kervao.fr dockerd[210886]: time="2025-09-26T17:02:55.281188368+02:00" level=warning msg="WARNING: API is accessible on http://127.0.0.1:2375 without encryption>
sept. 26 17:02:55 ultra.kervao.fr dockerd[210886]: time="2025-09-26T17:02:55.281244407+02:00" level=info msg="Docker daemon" commit=library-import containerd-snapshotter=false storage>
sept. 26 17:02:55 ultra.kervao.fr dockerd[210886]: time="2025-09-26T17:02:55.281378785+02:00" level=info msg="Daemon has completed initialization"
sept. 26 17:02:55 ultra.kervao.fr dockerd[210886]: time="2025-09-26T17:02:55.804448712+02:00" level=info msg="API listen on /var/run/docker.sock"
sept. 26 17:02:55 ultra.kervao.fr systemd[1]: Started docker.service.
sept. 26 17:02:55 ultra.kervao.fr dockerd[210886]: time="2025-09-26T17:02:55.804558097+02:00" level=info msg="API listen on 127.0.0.1:2375"

to see if Docker is working correctly, we will type

Docker Run Hello World

Here is the result

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
17eec7bbc9d7: Pull complete
Digest: sha256:54e66cc1dd1fcb1c3c58bd8017914dbed8701e2d8c74d9262e26bd9cc1642d31
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

To have Docker launch on every reboot, type

systemctl enable docker

We will create the /etc/frigate and /etc/frigate/config directories ; the records will be stored in the /media/frigate directory. We return to /etc/frigate/config where I created the docker-compose.yml file which will contain

services:
  frigate:
    container_name: frigate
    privileged: true # this may not be necessary for all setups
    network_mode: host # j'ai dû rajouter cette ligne pour accéder à ma caméra restreamée avec mediamtx
    restart: unless-stopped

    stop_grace_period: 30s # allow enough time to shut down the various services
    image: ghcr.io/blakeblackshear/frigate:stable
    shm_size: "512mb" # update for your cameras based on calculation above
    devices:
    
- /dev/bus/usb:/dev/bus/usb # ligne pour l'accélérateur USB Google Coral, à commenter sinon
     - /dev/dri/renderD128:/dev/dri/renderD128 # For intel hwaccel, needs to be updated for your hardware

    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /etc/frigate/config:/config
      - /media/frigate:/media/frigate
      - type: tmpfs # Optional: 1GB of memory, reduces SSD/SD Card wear
        target: /tmp/cache
        tmpfs:
          size: 1000000000
    ports: #section inutile avec le mode réseau host
      - "8971:8971" # port de l'interface navigateur
      #- "8554:8554" # RTSP feeds, j'ai mis en commentaire car conflit avec mediamtx, utile pour renvoyer le flux vidéo vers homeassistant
      - "8555:8555/tcp" # WebRTC over tcp
      - "8555:8555/udp" # WebRTC over udp

[ back to top of page ]

and config.yaml in which we will define the cameras and objects to detect (list here https://docs.frigate.video/configuration/objects )


mqtt:
  enabled: false
cameras:
  Camera-sud:
    ffmpeg:
      inputs:
        - path: rtsp://frigate:passwd@192.168.2.110
          roles:
            - detect
            - record
      hwaccel_args: preset-vaapi
    objects:
      track:
        - person
        - dog
        - cat
        - bird
 
       - bicycle
        - car
        - motorcycle
    detect:
      width: 1280
      height: 720
    record:
      enabled: true
      retain:
        days: 7
        mode: all
  Camera-entree:
    ffmpeg:
      inputs:
        - path: rtsp://frigate:passwd@192.168.2.112
          roles:
            - detect
            - record
      hwaccel_args: preset-vaapi
    objects:
      track:
        - person
        - dog
        - cat
        - bird
 
       - bicycle
        - car
        - motorcycle
    detect:
      width: 1280
      height: 720
    record:
      enabled: true
      retain:
        days: 7
        mode: all
  Camera-piscine:
    ffmpeg:
      inputs:
        - path: rtsp://frigate:passwd@192.168.2.200:554/ch0_1.264
          roles:
            - detect
            - record
    objects:
      track:
        - person
        - dog
        - cat
        - bird

    detect:
      width: 800
      height: 448
    record:
      enabled: true
      retain:
        days: 7
        mode: all
  Camera-ouest:
    ffmpeg:
      inputs:
        - path: rtsp://ultra.kervao.fr:8554/cam1
          roles:
            - detect
            - record
    objects:
      track:

        - person
        - dog
        - cat
        - bird

    detect:
      width: 640
      height: 360
    record:
      enabled: true
      retain:
        days: 7
        mode: all
detectors:
  cpu1:
    type: cpu
    num_threads: 3
detect:
  enabled: true
version: 0.16-0

If you have a Google Coral USB accelerator , we will replace it with the detectors.

 coral:
    type: edgetpu
    device: usb

Then type in this same directory

docker compose -f docker-compose.yml up -d

Here is the result: 9.6s

+] Running 10/10
 ✔ frigate 9 layers [⣿⣿⣿⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                                                                                           79.5s
   ✔ b1badc6e5066 Pull complete                                                                                                                                                   1.2s
   ✔ 4f4fb700ef54 Pull complete                                                                                                                                                   0.3s
   ✔ 14d4601b76c8 Pull complete                                                                                                                                                  14.6s
   ✔ cab46c26a5aa Pull complete                                                                                                                                                   1.1s
   ✔ 6891a7512d41 Pull complete                                                                                                                                                  14.3s
   ✔ b44b002328e4 Pull complete                                                                                                                                                   8.3s
   ✔ 8074b201d282 Pull complete                                                                                                                                                   8.6s
   ✔ d823104cefbd Pull complete                                                                                                                                                   9.0s
   ✔ f86078113133 Pull complete                                                                                                                                                   9.6s
[+] Running 2/2
 ✔ Network config_default  Created                                                                                                                                                0.1s
 ✔ Container frigate       Started

some useful commands, restart frigate

docker restart frigate

stopper frigate

docker stop frigate 
[ back to top of page ]

First launch

Frigate is now installed, launched, and accessible locally from the browser by typing

https://ultra.kervao.fr:8971/

To find out the password you will need to type

Docker logs frigate

and we see

2025-09-26 17:46:21.528704726  [2025-09-26 17:46:21] frigate.app                    INFO    : ********************************************************
2025-09-26 17:46:21.529867665  [2025-09-26 17:46:21] frigate.app                    INFO    : ********************************************************
2025-09-26 17:46:21.530590965  [2025-09-26 17:46:21] frigate.app                    INFO    : ***    Auth is enabled, but no users exist.          ***
2025-09-26 17:46:21.531237207  [2025-09-26 17:46:21] frigate.app                    INFO    : ***    Created a default user:                       ***
2025-09-26 17:46:21.542212889  [2025-09-26 17:46:21] frigate.app                    INFO    : ***    User: admin                                   ***
2025-09-26 17:46:21.566794613  [2025-09-26 17:46:21] frigate.app                    INFO    : ***    Password: 2bf8aeb98g16b66f54e70a8e8f121076   ***
2025-09-26 17:46:21.577589942  [2025-09-26 17:46:21] frigate.app                    INFO    : ********************************************************
2025-09-26 17:46:21.598394530  [2025-09-26 17:46:21] frigate.app                    INFO    : ********************************************************

With a TPU, we should get a message that looks like this.

2025-10-30 07:55:40.442764361  [2025-10-30 07:55:40] frigate.detectors.plugins.edgetpu_tfl INFO    : TPU found
2025-10-30 07:55:40.443899970  INFO: Created TensorFlow Lite XNNPACK delegate for CPU.

This allows you to log in, and here's the general interface with the latest events at the top and the live views just below.

With only the TPU, it's practically unusable on a daily basis; the program constantly uses almost 100% of the resources.

And with a TPU, it's like night and day!!

[ back to top of page ]

Configuration

Before going any further, it is important to understand some basic concepts of how Frigate works. We talk about alerts and detections. Alerts are based on detections but are considered priority events to be reported, while detections are less significant events that do not warrant notification but are still recorded and visible in the event review (see the documentation in English here https://docs.frigate.video/configuration/review/ ).

Let's move on to the settings, accessible via the gear icon in the bottom left corner of the main screen. In the first tab, User Interface , there are general settings that I haven't changed. In the Augmented Data tab , you can enable them (they are disabled by default).

  • semantic search allows you to find tracked objects in your event review using either the image itself, a user-defined text description, or an automatically generated description.
  • facial recognition
  • license plate recognition
  • bird identification

We start with the Masks/Zones tab. For each camera selectable from the blue button in the upper right corner, we define detection zones; other areas of the image will be ignored for detection.



Note that you can select the type of object that can be detected and estimate the speed of the movement.



On the other hand, if we want only people and cars to be considered as alerts, we will need to modify the configuration file for the camera in question in the review section by adding a sub-section labels like this

    review:
      alerts:
        labels:
          - person
          - car
        required_zones: Zone-det-camera-sud
      detections:
        required_zones: Zone-det-camera-sud

We can also declare motion masks to prevent detection in places where there is a risk of unwanted movement (vegetation), which can disrupt object tracking.



To prevent your car, usually parked in its spot, from appearing as a false positive, you will need to create a specific object mask like this:


Note that you will need to restart Frigate for this to take effect; this can be done from the Settings menu.

We now return to the Camera Settings tab , in the configuration below, only Person and Car objects will be displayed as alerts in the predefined area and other detected objects will be classified as detections in the same area.

and so on for all the cameras.

In the Motion Settings tab , you can fine-tune certain parameters for each camera so that it is considered as movement; I left the default values.


The Debug tab can be useful for displaying certain information in real time. The Users tab , as its name suggests, allows you to manage users. Two types of users are possible: administrators have access to all interface features, while observers are limited to viewing cameras, reviewing events, and viewing recording history within the user interface. The Notifications tab allows you to send email alerts.

Regarding recordings, by default we have

    record:
      enabled: true
      retain:
        days: 7
        mode: all

This means that both alerts and detections are recorded and stored for 7 days. For more detailed recording management, see this page: https://docs.frigate.video/configuration/record/

[ back to top of page ]

Use

Now let's return to the main interface. We saw earlier that the main view links to the camera views; it is accessible by clicking on the icon representing a camera on the left.

Clicking on the Event Review on the left displays all recent events (alerts, detections, movement). The detected object appears as an icon in the top left corner of the image; you can access the replay by clicking on the image. You can save the review by clicking on Mark these items as reviewed at the bottom.



The Explorer menu on the left allows you to display all detected objects, which can be filtered using the tools in the top right corner.



For the rest, I refer you to the Frigate documentation for usage instructions; here are some interesting URLs.

https://docs.frigate.video/guides/getting_started
https://community.jeedom.com/t/tuto-integrer-frigate-et-faire-de-la-reconnaissance-video-dobjet-par-ia-en-local-dans-son-jeedom/117108
https://www.simplehomelab.com/frigate-docker-guide/



View Frigate from a mobile device

Regarding remote viewing on a mobile device, there is indeed an unofficial Android application , but I don't really see the point because simply accessing the address directly (once it's made accessible on the internet) from a mobile browser is quite user-friendly, as you can see below.