Frigate NVR Setup¶

Frigate is a self-hosted NVR running inside a Docker container on a privileged Proxmox LXC, providing real-time AI object detection, recording, and snapshot capture for all four PoE cameras — completely local with no cloud dependencies.
Why Frigate?¶
The FUTO philosophy is clear: own your surveillance footage locally. Cloud-based camera systems (Ring, Nest) send your video to someone else's servers. Frigate runs entirely locally, stores recordings on your own NAS, and does AI-based object detection without phoning home.
The Reolink RLC-510A cameras support RTSP streaming, which Frigate ingests directly. No cloud account required.
Architecture¶
graph LR
subgraph IoT["IoT VLAN (10.0.30.x)"]
DB["Doorbell<br/>10.0.30.117"]
FC["Front Camera<br/>10.0.30.114"]
SC["Side Camera<br/>10.0.30.115"]
RC["Rear Camera<br/>10.0.30.116"]
end
subgraph MGMT["Management VLAN (10.0.10.x)"]
Frigate["Frigate NVR<br/>LXC 102 · 10.0.10.104"]
NAS["Pi 5 NAS<br/>10.0.10.50"]
HA["Home Assistant<br/>10.0.10.60"]
end
DB -- "RTSP" --> Frigate
FC -- "RTSP" --> Frigate
SC -- "RTSP" --> Frigate
RC -- "RTSP" --> Frigate
Frigate -- "NFS" --> NAS
Frigate -- "MQTT" --> HA
Hardware¶
Cameras:
| Location | Model | IP | MAC |
|---|---|---|---|
| Doorbell | Reolink PoE Doorbell | 10.0.30.117 |
ec:71:db:xx:xx:xx |
| Front | Reolink RLC-510A (5MP) | 10.0.30.114 |
ec:71:db:xx:xx:xx |
| Side | Reolink RLC-510A (5MP) | 10.0.30.115 |
ec:71:db:xx:xx:xx |
| Rear | Reolink RLC-510A (5MP) | 10.0.30.116 |
ec:71:db:xx:xx:xx |
All cameras are powered via PoE from the USW-Lite-8-PoE switch with ports assigned to the IoT VLAN profile.
Compute: Frigate runs as LXC container 102 on pve1 (HP EliteDesk 800 G3 Mini, i7-6700T). The Intel HD 530 iGPU provides both VAAPI hardware video decoding and OpenVINO AI object detection.
LXC Container¶
The Frigate container runs as a privileged LXC to allow GPU device passthrough and future Coral TPU support.
| Setting | Value |
|---|---|
| CT ID | 102 |
| Node | pve1 |
| IP | 10.0.10.104/24 |
| Gateway | 10.0.10.1 |
| RAM | 4096 MB |
| CPU | 4 cores |
| Disk | 16 GB (local-lvm) |
| Type | Privileged (unprivileged=0) |
| Features | nesting=1 |
Intel iGPU Passthrough¶
The Intel HD 530 iGPU is passed through to the LXC for hardware-accelerated video decoding (VAAPI) and AI inference (OpenVINO). This is configured in the container's Proxmox config file.
On pve1 host — edit /etc/pve/lxc/102.conf:
lxc.cgroup2.devices.allow: c 226:* rwm
lxc.mount.entry: /dev/dri dev/dri none bind,optional,create=dir
After adding these lines, restart the container. Frigate auto-detects the GPU and enables VAAPI decoding.
Storage¶
Recordings and snapshots are stored on the Pi 5 NAS (10.0.10.50) via NFS.
NAS side (OMV7):
- Create shared folder
frigate-recordingson the RAID 5 array - Enable NFS share for
10.0.10.0/24withrw,no_root_squashpermissions
Proxmox host side — mount and bind into LXC:
Inside the container, the NFS mount appears at /mnt/nas-frigate and is mapped to /media/frigate in the Docker container via the compose file.
Docker Compose¶
version: "3.9"
services:
frigate:
container_name: frigate
privileged: true
restart: unless-stopped
image: ghcr.io/blakeblackshear/frigate:stable
shm_size: "640mb"
volumes:
- /etc/localtime:/etc/localtime:ro
- ./config:/config
- /mnt/nas-frigate:/media/frigate
- type: tmpfs
target: /tmp/cache
tmpfs:
size: 1000000000
ports:
- "5000:5000"
- "8554:8554"
- "8555:8555/tcp"
- "8555:8555/udp"
devices:
- /dev/dri:/dev/dri
SHM Size
With 4 cameras (8 streams total — main + sub per camera), the default 64MB SHM is far too small. Frigate recommends at least 634MB. Set shm_size: "640mb" or higher. Insufficient SHM causes frame drops, decoder crashes, and intermittent black screens.
Frigate Configuration¶
The full config/config.yml with all four cameras, OpenVINO detection, VAAPI hardware decode, and dual-stream recording with tiered retention:
mqtt:
enabled: true
host: 10.0.10.60
port: 1883
user: mqtt
password: "<your-mqtt-password>"
ffmpeg:
hwaccel_args: preset-vaapi
go2rtc:
streams:
doorbell:
- rtsp://admin:<password-url-encoded>@10.0.30.117:554/h264Preview_01_main
doorbell_sub:
- rtsp://admin:<password-url-encoded>@10.0.30.117:554/h264Preview_01_sub
front_camera:
- rtsp://admin:<password-url-encoded>@10.0.30.114:554/h264Preview_01_main
front_camera_sub:
- rtsp://admin:<password-url-encoded>@10.0.30.114:554/h264Preview_01_sub
side_camera:
- rtsp://admin:<password-url-encoded>@10.0.30.115:554/h264Preview_01_main
side_camera_sub:
- rtsp://admin:<password-url-encoded>@10.0.30.115:554/h264Preview_01_sub
rear_camera:
- rtsp://admin:<password-url-encoded>@10.0.30.116:554/h264Preview_01_main
rear_camera_sub:
- rtsp://admin:<password-url-encoded>@10.0.30.116:554/h264Preview_01_sub
detectors:
ov:
type: openvino
device: GPU
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
detect:
enabled: true
cameras:
doorbell:
ffmpeg:
inputs:
- path: rtsp://127.0.0.1:8554/doorbell
roles:
- record
- path: rtsp://127.0.0.1:8554/doorbell_sub
roles:
- detect
detect:
width: 640
height: 480
fps: 5
record:
enabled: true
retain:
days: 3
mode: motion
alerts:
retain:
days: 14
detections:
retain:
days: 14
snapshots:
enabled: true
retain:
default: 14
objects:
track:
- person
- car
- dog
- cat
front_camera:
ffmpeg:
inputs:
- path: rtsp://127.0.0.1:8554/front_camera
roles:
- record
- path: rtsp://127.0.0.1:8554/front_camera_sub
roles:
- detect
detect:
width: 640
height: 480
fps: 5
record:
enabled: true
retain:
days: 3
mode: motion
alerts:
retain:
days: 14
detections:
retain:
days: 14
snapshots:
enabled: true
retain:
default: 14
objects:
track:
- person
- car
- dog
- cat
side_camera:
ffmpeg:
inputs:
- path: rtsp://127.0.0.1:8554/side_camera
roles:
- record
- path: rtsp://127.0.0.1:8554/side_camera_sub
roles:
- detect
detect:
width: 640
height: 480
fps: 5
record:
enabled: true
retain:
days: 3
mode: motion
alerts:
retain:
days: 14
detections:
retain:
days: 14
snapshots:
enabled: true
retain:
default: 14
objects:
track:
- person
- car
- dog
- cat
rear_camera:
ffmpeg:
inputs:
- path: rtsp://127.0.0.1:8554/rear_camera
roles:
- record
- path: rtsp://127.0.0.1:8554/rear_camera_sub
roles:
- detect
detect:
width: 640
height: 480
fps: 5
record:
enabled: true
retain:
days: 3
mode: motion
alerts:
retain:
days: 14
detections:
retain:
days: 14
snapshots:
enabled: true
retain:
default: 14
objects:
track:
- person
- car
- dog
- cat
version: 0.16-0
semantic_search:
enabled: true
model_size: large
face_recognition:
enabled: true
model_size: large
lpr:
enabled: true
classification:
bird:
enabled: false
Stream Architecture¶
Each camera uses a dual-stream approach to balance detection quality with storage efficiency:
- Main stream (
h264Preview_01_mainat 2560×1920) → used for recording, saving full 5MP quality to the NAS - Sub stream (
h264Preview_01_subat 640×480) → used for AI detection, already close to the 300×300 model input size so minimal CPU is needed for downscaling
All streams pass through go2rtc for restreaming, which provides stable WebRTC playback in the UI and prevents multiple direct connections to the cameras.
VAAPI hardware decode is enabled globally via ffmpeg: hwaccel_args: preset-vaapi, offloading video decoding to the Intel HD 530 iGPU for all cameras including the doorbell.
Tiered Retention (Frigate 0.16 schema)¶
Frigate 0.16 uses alerts and detections keys (not the old events key) for tiered retention:
| Retention Type | Duration | What It Keeps |
|---|---|---|
| Motion | 3 days | Any segment with motion detected |
| Alerts | 14 days | Segments where tracked objects triggered alerts |
| Detections | 14 days | Segments where AI detected objects of interest |
This tiered approach dropped NAS usage from 99% to ~30% steady state — well within the 2.58 TiB usable capacity.
AI Features¶
Frigate 0.16 includes several AI capabilities enabled in this deployment:
- Semantic search — natural language search across recorded events (large model, GPU-accelerated)
- Face recognition — identifies known faces from snapshots (large model, GPU-accelerated)
- LPR (License Plate Recognition) — reads number plates from detected vehicles
- Object tracking — person, car, dog, and cat detection on all cameras
Detection Performance¶
The Intel HD 530 iGPU running OpenVINO provides significant performance improvements over CPU-based detection:
| Metric | CPU Detector | OpenVINO (GPU) |
|---|---|---|
| Inference speed | 482 ms | 8.98 ms |
| Detector CPU usage | 174.7% | 14.0% |
| Improvement | — | 53× faster |
This performance headroom comfortably supports all 4 cameras simultaneously with room to spare.
Firewall Rules¶
Frigate needs cross-VLAN access to reach the cameras on the IoT VLAN.
OPNsense → Firewall → Rules → MGMT interface:
| Action | Protocol | Source | Destination | Description |
|---|---|---|---|---|
| Pass | TCP/UDP | 10.0.10.104 |
10.0.30.0/24 |
Allow Frigate to access cameras |
Network Cabling¶
All four cameras are wired with outdoor-rated Cat6 cable to the USW-Lite-8-PoE switch. Cable runs were planned using floor plan measurements:
| Camera | Approximate Run |
|---|---|
| Doorbell (front door) | ~12m |
| Front (front of property) | ~15m |
| Side (side passage) | ~20m |
| Rear (back garden) | ~30m |
Total cable used: approximately 77 metres of outdoor-rated Cat6.
Adding New Cameras¶
To add a camera to the system:
- Connect the camera to a PoE port on the switch with IoT VLAN profile
- Create a static DHCP reservation in OPNsense (Services → DHCPv4 → IoT)
- Set admin credentials on the camera via its web UI
- Add the RTSP stream URLs to
go2rtc.streamsin the Frigate config - Add the camera definition to the
camerassection - Restart Frigate:
docker compose restart frigate
Storage Considerations¶
With the corrected stream architecture (main stream for recording, sub stream for detection), storage usage is significantly reduced compared to recording the full 5MP main stream:
Estimated storage usage with tiered retention:
| Scenario | Daily (est.) | Steady State |
|---|---|---|
| 4 cameras, main stream record, 3d motion + 14d alerts | ~25–40 GiB | ~500–700 GiB |
The NAS has 2.58 TiB usable, providing over a terabyte of headroom.
Home Assistant Integration¶
Frigate integrates with Home Assistant via MQTT (Mosquitto broker), enabling:
- Live camera feeds on the HA dashboard using picture-glance cards with native Frigate camera entities (no iframes needed)
- Mobile push notifications via the Frigate Notifications blueprint from HACS — sends snapshot with bounding box when a person is detected at the doorbell
- Event-driven automations based on object detection events
For full Home Assistant setup, see the Home Assistant guide.
Lessons Learned¶
Stream roles matter — sub for detect, main for record. The detection model input is 300×300 pixels. Sending 5MP frames to the detector wastes massive CPU on downscaling. The sub-stream at 640×480 is already close to model input size. Meanwhile, the main stream records at full 5MP quality to the NAS.
URL-encode special characters in passwords. The # character is interpreted as a URL fragment delimiter in RTSP URLs, silently truncating the password. Use %23 instead of #.
SHM size must scale with camera count. The default 256MB is adequate for 1–2 cameras but causes crashes with 4. Frigate logs the recommended minimum — watch for the warning on startup.
VAAPI globally with preset-vaapi. Enable hardware decode for all cameras at the global ffmpeg level rather than per-camera. This ensures the doorbell and all other cameras use iGPU decode.
Tiered retention saves storage. The jump from flat 14-day retention to 3-day motion / 14-day alerts dropped NAS usage from 99% to ~30%.
VLAN double-tagging. If the Proxmox host bridge already carries the management VLAN as untagged traffic, do not add a VLAN tag to the LXC network interface. Double-tagging prevents the container from getting an IP address.
go2rtc restreaming is essential. Connecting Frigate directly to camera RTSP streams causes multiple concurrent connections to each camera, leading to instability. Routing everything through go2rtc ensures a single connection per camera with stable restreaming to all consumers.