selfhosted-apps-docker/frigate/readme.md

17 KiB

Frigate

guide-by-example

logo

WORK IN PROGRESS
WORK IN PROGRESS
WORK IN PROGRESS

Purpose & Overview

Managing security cameras - recording, detection, notifications.

Frigate is a software NVR - network video recorder.
Simple, clean web-based interface with possible integration in to home assistant and its app.

Frigate offers powerful AI object detection, by using OpenCV and Tensorflow. In contrast to cameras of old time which just detect movement, Frigate can recognize if object in view is a cat, a car or a human.

This detection is cpu heavy and to ease the load Google Coral TPU is recommended if planning to run multiple cameras with detection.
Recently OpenVINO has been integrated, which should allow use of igpu of intel 6th+ gen cpus as a detector.

But do not have too high expectations. False positives are plenty, especially when shadows are present. Same with not detecting a cat when one sits right there. Config allows for some improvements and the AI model will likely get better with time too.

Open source, written in Python and JavaScript.

Terminology
  • PoE - Power over ethernet, camera is powered by the same cat cable that carries data. You want POE(802.3af) or POE+(802.3at), none of the passive poe by mikrotik or ubiquity.
  • IR - infrared light for night vision, attracts bugs that see it, reflects off walls or shiny surfaces, loss of color information
  • onvif - It's a forum. It strives to maintain an industry standard that allows stuff from different manufacturers to work.
  • rtsp - a protocol for controling remotely cameras and streaming
  • ptz - Pan-Tilt-Zoom allows remote movement of a camera
  • IoT - Internet of Things
  • mqtt - Messaging protocol widely used in IoT. Youtube playlist about it.

Cameras choice

Frigate got a page for that.

My opinion

  • Dahua - If you got decent budget, they have good stuff and very rich configuration. Going for that 1/1.8" sensor for good low light performance with IR being off, though dont expect magic. I also dealt with hikvision and sunell and dahua felt most solid and modern.

  • The cameras I am actually playing with are cheap TP-Link 4MP cameras.
    I do not have issues with them. Followed frigates brand specific configuration which says to switch all streams to H264 and turn off Smart Coding.

    • VIGI C440 - fuckup as its an interior camera and I did not notice when ordering. It's stil outside as it's not directly on elements, survived one winter so far.
    • VIGI C240 - cheap and exterior, enough settings to feel fine. It actually decetnly see at night without IR, but you realize its kinda lie as if something moves there its a smudge at best or invisible predator at worst.
    • some random aliexpress camera with ptz

Once I am running frigate and cameras for some real time... more than a year, I will decide which cameras to get long term.

Files and directory structure

/mnt/
└── 🗁 frigate_hdd/
|   └── 🗁 frigate_media/
|
/home/
└── ~/
    └── docker/
        └── frigate/
            ├── 🗁 frigate_config/
            |    └── 🗋 config.yml
            ├── 🗋 .env
            └── 🗋 docker-compose.yml
  • frigate_media/ - storage for frigate recordings and jpg snapshots
  • frigate_config/ - config and database directory
  • config.yml - main frigate config file
  • .env - a file containing environment variables for docker compose
  • docker-compose.yml - a docker compose file, telling docker how to run the containers

You need to create frigate_config directory which gets mounted in to the container, and in to it place config.yml.
frigate_media directory should be placed on a HDD drive as nonstop writes would exhaust ssd drive writes, or would be eating in to network bandwith if storage would be NAS.

docker-compose

This docker compose is based off the official one except few changes.
Using bind mounts instead of volumes, moved variables to the .env file.
Increased shm_size which is a preset max ram for interprocess communication of the container.
Privileged mode is used, which allows access to the gpu stats and avoids issue with access to recordings and having to deal with permissions.

For hwaccel support theres devices section with renderD128 mapped in to the container. Check the /dev/dri/ path to see what you got there.
The section can be deleted if planning to use just the cpu. Or adjusted for colar or pcie gpu.

docker-compose.yml

services:

  frigate:
    image: ghcr.io/blakeblackshear/frigate:0.13.2
    container_name: frigate
    hostname: frigate
    restart: unless-stopped
    env_file: .env
    privileged: true
    shm_size: "256mb"
    devices:
      - /dev/dri/renderD128 # for intel hwaccel, needs to be updated for your hardware
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ./frigate_config:/config
      - /mnt/frigate_hdd/frigate_media:/media/frigate
      - type: tmpfs # 1GB of memory
        target: /tmp/cache
        tmpfs:
          size: 1000000000
    ports:
      - "5000:5000" # Web GUI
      - "8554:8554" # RTSP feeds
      - "8555:8555/tcp" # WebRTC over tcp
      - "8555:8555/udp" # WebRTC over udp

networks:
  default:
    name: $DOCKER_MY_NETWORK
    external: true

.env

# GENERAL
DOCKER_MY_NETWORK=caddy_net
TZ=Europe/Bratislava

# FRIGATE
FRIGATE_RTSP_USER: "admin"
FRIGATE_RTSP_PASSWORD: "dontlookatmekameras"

All containers must be on the same network.
Which is named in the .env file.
If one does not exist yet: docker network create caddy_net

Reverse proxy

Caddy is used, details here.

Caddyfile

cam.{$MY_DOMAIN} {
  reverse_proxy frigate:5000
}

To allow only traffic from LAN to have access to your Frigate.

Caddyfile

(LAN_only) {
  @fuck_off_world {
    not remote_ip private_ranges
  }
  respond @fuck_off_world 403
}

cam.{$MY_DOMAIN} {
  import LAN_only
  reverse_proxy frigate:5000
}

Configuration

Configuration is done through singular file config.yml
Here we be in small steps adding to it, making sure stuff works before moving to a next thing. As dumping full config.yml is just too much for first time running.

Preparation

Connect a camera to your network.

Find url of your camera streams, either by googling your model, or theres a handy windows utility - onvif-device-manager. Unfortunately all official urls seem dead, this worked for me and passed virustotal at the time. There are also comments with some links at its sourceforge page.
Camera discovery of onvif-device-manager is almost instant, if the camera requires credentials, set them in the top left corner.
In live view there should be stream url displayed. Like: "rtsp://10.0.19.41:554/stream1"

Ideally your camera has several streams. A primary one in full resolution full frame rate for recording, and then secondary one in much smaller resolution and fps for observing.

First config - one camera

Bare config that should show camera stream once frigate is running.
Credentails are contained in the url - rtsp://username:password@ip:port/url

Disabled mqtt since no communication with home assistant or anything else. And a single camera stream that pulls credentials from environment variables.

config-1.yml

mqtt:
  enabled: false
cameras:
  K1-Gate:
    ffmpeg:
      inputs:
        - path: rtsp://{FRIGATE_RTSP_USER}:{FRIGATE_RTSP_PASSWORD}@10.0.19.41:554/stream1

Second config - detection, recording, two cameras

config-2.yml

mqtt:
  enabled: false

detectors:
  default_detector_for_all:
    type: cpu

objects:
  track:
    - person
    - cat
    - dog

record:
  enabled: true
  retain:
    days: 60
    mode: all
  events:
    retain:
      default: 360
      mode: motion

snapshots:
  enabled: true
  crop: true
  retain:
    default: 360

birdseye:
  mode: continuous

cameras:
  K1-Gate:
    ffmpeg:
      inputs:
        - path: rtsp://{FRIGATE_RTSP_USER}:{FRIGATE_RTSP_PASSWORD}@10.0.19.41:554/stream1
          roles:
            - record
        - path: rtsp://{FRIGATE_RTSP_USER}:{FRIGATE_RTSP_PASSWORD}@10.0.19.41:554/stream2
          roles:
            - detect
    detect:
      width: 640
      height: 480
      fps: 5
    motion:
      mask:
        - 640,480,640,0,0,0,0,480,316,480,308,439,179,422,162,121,302,114,497,480

  K2-Pergola:
    ffmpeg:
      inputs:
        - path: rtsp://{FRIGATE_RTSP_USER}:{FRIGATE_RTSP_PASSWORD}@10.0.19.42:554/stream1
          roles:
            - record
        - path: rtsp://{FRIGATE_RTSP_USER}:{FRIGATE_RTSP_PASSWORD}@10.0.19.42:554/stream2
          roles:
            - detect
    detect:
      width: 640
      height: 480
      fps: 5
    motion:
      mask:
        - 640,78,640,0,0,0,0,480,316,480,452,171


If a camera is runnig and stream can be viewed, it's time to move to core NVR functions like recording and basic detection.

Settings in root of the config file, global - applicable for all cameras:

  • detectors - Could be omitted as the default is the cpu, but its good to have this explicitly stated and ready as most people will be switching to non-cpu detection.
  • objects - What the detector will be looking for. Later on this config can grow as more specific parameters are added.
  • record - Globally enabled record and set retention time on all cameras.
  • snapshots - If jpg pictures of detect events should be made and some of its options.
  • birdseye - Webgui section where one can see current view of all cameras. It's enabled by default, but the default mode being objects means it only shows cameras that detected something in the last 30s. So it is switched to continuous mode.

In per camera section:

  • roles - Added lower resolution stream and roles define which to record and which to use for detection.
  • detect - Section defines resolution and fps for detect job, you want it to match what camera is sending. This can be often set directly on a camera. You can then check if its respected with onvif-device-manager in its profile section, or in Frigate > System > FFPROBE
  • Motion mask - Defines which parts of the view to ignore. Watch the youtube video.

You might wanna run the 2nd config for a day or two to see how it behaves.

Third config - intel openvino and hardware acceleration

config-3.yml

mqtt:
  enabled: false

detectors:
  ov:
    type: openvino
    device: AUTO
    model:
      path: /openvino-model/ssdlite_mobilenet_v2.xml

model:
  width: 300
  height: 300
  input_tensor: nhwc
  input_pixel_format: bgr
  labelmap_path: /openvino-model/coco_91cl_bkgr.txt

ffmpeg:
  hwaccel_args: preset-vaapi

detect:
  max_disappeared: 2500

objects:
  track:
    - person
    - cat
    - dog

record:
  enabled: true
  retain:
    days: 60
    mode: all
  events:
    retain:
      default: 360
      mode: motion

snapshots:
  enabled: true
  crop: true
  retain:
    default: 360

birdseye:
  mode: continuous

cameras:
  K1-Gate:
    ffmpeg:
      inputs:
        - path: rtsp://{FRIGATE_RTSP_USER}:{FRIGATE_RTSP_PASSWORD}@10.0.19.41:554/stream1
          roles:
            - record
        - path: rtsp://{FRIGATE_RTSP_USER}:{FRIGATE_RTSP_PASSWORD}@10.0.19.41:554/stream2
          roles:
            - detect
    detect:
      width: 640
      height: 480
      fps: 5
    motion:
      mask:
        - 640,480,640,0,0,0,0,480,316,480,308,439,179,422,162,121,302,114,497,480

  K2-Pergola:
    ffmpeg:
      inputs:
        - path: rtsp://{FRIGATE_RTSP_USER}:{FRIGATE_RTSP_PASSWORD}@10.0.19.42:554/stream1
          roles:
            - record
        - path: rtsp://{FRIGATE_RTSP_USER}:{FRIGATE_RTSP_PASSWORD}@10.0.19.42:554/stream2
          roles:
            - detect
    detect:
      width: 640
      height: 480
      fps: 5
    motion:
      mask:
        - 640,78,640,0,0,0,0,480,316,480,452,171


Only two changes in the 3rd config.

I started to have daily freezes first time I switched to hwaccl and igpu detection. I was ready to tackle it based on some github disscussion, but once I started from scratch with latest version I had no more freezes.

But maybe it will comes, as I had mqtt and ntfy working at that time.

Fourth config - notifications with mqtt and ntfy

WORK IN PROGRESS WORK IN PROGRESS WORK IN PROGRESS

Now is the time to get some push notifications about events happenig on cameras.

Will be using ntfy for notifications.

The first result when googling for "frigate ntfy" is this guide. But EMQX had major interface change since emqx:5.3.2 that is used in the guide.

Using ntfy, gude here.

Following this guide where emqx is setup as middle man.

docker-compose.yml

services:

  frigate:
    image: ghcr.io/blakeblackshear/frigate:0.13.2
    container_name: frigate
    hostname: frigate
    restart: unless-stopped
    env_file: .env
    privileged: true
    shm_size: "256mb"
    devices:
      - /dev/dri/renderD128 # for intel hwaccel, needs to be updated for your hardware
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ./frigate_config:/config
      - /mnt/frigate_hdd/frigate_media:/media/frigate
      - type: tmpfs # 1GB of memory
        target: /tmp/cache
        tmpfs:
          size: 1000000000
    ports:
      - "5000:5000" # Web GUI
      - "8554:8554" # RTSP feeds
      - "8555:8555/tcp" # WebRTC over tcp
      - "8555:8555/udp" # WebRTC over udp

  emqx:
    image: emqx/emqx:5.3.2
    container_name: emqx
    hostname: frigate
    restart: unless-stopped
    env_file: .env
    user: root
    volumes:
      - ./emqx_data:/opt/emqx/data
    ports:
      - 1883:1883
      - 8083:8083
      - 8084:8084
      - 8883:8883
      - 18083:18083 # Web GUI

networks:
  default:
    name: $DOCKER_MY_NETWORK
    external: true

Current full config

with intel igpu openvino mqtt ntfy

Previously when I tried openvino igpu hw acceleration I had the server daily freeze. Now I setup this config expecting freezes and getting ready to try yolo model from github comments, but no freeze yet for few days..




Notifications

Update

Manual image update:

  • docker-compose pull
  • docker-compose up -d
  • docker image prune