How to Install Frigate NVR (Record Security Cameras with Object Detection)

Cloud camera subscriptions charge per camera, keep your footage on their servers, and alert you every time a leaf moves. Frigate records any camera that speaks RTSP to your own disk, runs real object detection — person, car, dog, cat — so alerts mean something, and keeps clips of events separately from continuous recording. It's the standard NVR for Home Assistant people, and it runs on the server you already have.
Quick reference
| Task | What |
|---|---|
| Folder | ~/docker/frigate/compose.yaml + config/config.yml |
| Web | http://server-ip:5000 |
| Cameras | any with an RTSP stream (Reolink, Amcrest, Hikvision, Dahua, Tapo, Unifi) |
| Detection | CPU works for 1–2 cameras; a Google Coral USB or an Intel/NVIDIA GPU for more |
| Storage | /mnt/data/frigate — on a big drive; it writes constantly |
| Home Assistant | the Frigate integration (via HACS) + MQTT |
1. Before you start
- Get each camera's RTSP URL from its manual or app, usually like rtsp://user:pass@192.168.1.60:554/h264Preview_01_main. Most cameras also offer a low-resolution sub stream — Frigate uses that for detection and the main one for recording.
- Give cameras fixed IPs (tutorial 8) and put them on a network that can't reach the internet if your router allows it.
- Detection on CPU is heavy. For more than a couple of cameras, a Coral USB accelerator (about the price of a camera) handles dozens at near-zero CPU, or use an Intel iGPU via OpenVINO.
2. The compose file
mkdir -p ~/docker/frigate/config && cd ~/docker/frigate
nano compose.yaml
services:
frigate:
image: ghcr.io/blakeblackshear/frigate:stable
container_name: frigate
privileged: true
shm_size: "256mb"
devices:
- /dev/bus/usb:/dev/bus/usb # Coral USB
- /dev/dri/renderD128 # Intel GPU for decoding
volumes:
- ./config:/config
- /mnt/data/frigate:/media/frigate
- /etc/localtime:/etc/localtime:ro
- type: tmpfs
target: /tmp/cache
tmpfs:
size: 1000000000
ports:
- "5000:5000"
- "8554:8554"
environment:
FRIGATE_RTSP_PASSWORD: ${CAM_PASSWORD}
restart: unless-stopped
Remove the devices lines you don't have.
3. The config file
nano config/config.yml
mqtt:
enabled: false
detectors:
coral:
type: edgetpu
device: usb
# cpu1:
# type: cpu
ffmpeg:
hwaccel_args: preset-vaapi
cameras:
front_door:
ffmpeg:
inputs:
- path: rtsp://admin:{FRIGATE_RTSP_PASSWORD}@192.168.1.60:554/h264Preview_01_sub
roles: [detect]
- path: rtsp://admin:{FRIGATE_RTSP_PASSWORD}@192.168.1.60:554/h264Preview_01_main
roles: [record]
detect:
width: 640
height: 360
objects:
track: [person, car, dog, cat]
record:
enabled: true
retain:
days: 7
mode: motion
alerts:
retain:
days: 30
snapshots:
enabled: true
retain:
default: 30
Use cpu1 instead of coral if you have no accelerator, and drop hwaccel_args without an Intel GPU. Each camera is a block under cameras:.
docker compose up -d
sudo ufw allow from 192.168.1.0/24 to any port 5000
docker compose logs -f
4. The web UI
http://192.168.1.50:5000: live view of every camera with detection boxes, Review for events (person at the front door at 14:02, with the clip), Explore to search everything, and the full recordings timeline. Click the camera → Debug to see what the detector sees — you'll want to draw motion masks over the road or a waving tree so they don't trigger. The config editor is in the UI too.
5. Retention and disk
record.retain.days: 7 with mode: motion keeps a week of footage where something moved; alerts (detected objects) are kept 30 days. A 2K camera at motion-only uses roughly 5–15 GB a week. Watch df -h for the first week and adjust. Frigate deletes oldest first and never fills the disk past its settings — but put /mnt/data/frigate on a drive that isn't the system one.
6. Home Assistant
Enable MQTT (mqtt: enabled: true, host: mosquitto — tutorial 96) and install the Frigate integration via HACS. Every camera, every detected object and every event becomes an entity: "notify my phone with the snapshot when a person is at the front door and nobody's home" is a five-line automation, and the Home Assistant app shows the clip.
Troubleshooting
"No frames received" for a camera. Wrong RTSP URL. Test it with ffplay rtsp://... on your PC, or VLC → Open Network Stream.
CPU at 100%. Detection on CPU with too many cameras or too high a detect resolution. Use the sub stream at 640×360, or buy the Coral.
Coral not found. lsusb should show "Global Unichip Corp". It needs the USB passthrough and privileged. First plug-in sometimes shows as a different ID until Frigate initialises it; restart the container.
Recordings choppy. Hardware decode isn't working (hwaccel_args), or the disk is slow. An SSD cache isn't needed, but a 5400 rpm USB drive behind a hub is.
Wrapping up
RTSP URLs, a compose file with the accelerator passed through, one camera block in the config, retention set. Cameras record to your disk, alerts only fire for people and cars, and Home Assistant can act on them. No subscription, no cloud, no leaf alerts.
