What you need
- Intel N100 / N150 / N305 mini PC with the iGPU enabled (Alder Lake-N has no NPU, so detection runs on the GPU)
- 16 GB RAM for 3 or more cameras (8 GB is workable for one or two)
- 128 GB+ NVMe, or a separate disk for recordings
- Ubuntu 24.04 LTS or Debian 13 with a 6.x kernel
- An IP camera that exposes an RTSP main stream and a lower-resolution substream
- Wired Ethernet between the mini PC and the cameras
1Confirm the iGPU is visible to the kernel
Frigate passes the render node into the container, so the host must expose /dev/dri/renderD128. If only card0 exists, the iGPU is disabled in the BIOS (look for an iGPU or IGD option, and a DVMT / IGD memory setting of 512 MB or more on boards that have one) or the i915 driver is not loaded. vainfo then tells you which codecs the media engine can decode.
ls -l /dev/dri
sudo apt install -y vainfo
vainfo --display drm --device /dev/dri/renderD128 | head -20
2Install Docker Engine and the Compose plugin
Frigate ships as a container image, so Docker Engine plus the Compose v2 plugin is all the host needs. Docker's convenience script sets up the official apt repository, which keeps later upgrades simple.
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
exec su - $USER
docker compose version
3Create the stack and pass the GPU through
Frigate needs three mounts: /config for configuration and the model, /media/frigate for recordings, and a tmpfs for the recording segment cache so the SSD is not hammered by short-lived files. The only device to pass in for an N100 is /dev/dri/renderD128; privileged mode is not required.
sudo mkdir -p /opt/frigate/config /opt/frigate/storage
cd /opt/frigate
services:
frigate:
container_name: frigate
restart: unless-stopped
stop_grace_period: 30s
image: ghcr.io/blakeblackshear/frigate:stable
shm_size: "512mb"
devices:
- /dev/dri/renderD128:/dev/dri/renderD128
volumes:
- /etc/localtime:/etc/localtime:ro
- /opt/frigate/config:/config
- /opt/frigate/storage:/media/frigate
- type: tmpfs
target: /tmp/cache
tmpfs:
size: 1000000000
ports:
- "8971:8971"
- "8554:8554"
- "8555:8555/tcp"
- "8555:8555/udp"
environment:
TZ: "Etc/UTC"
4Export the YOLOv9-t model to ONNX
Frigate 0.18 asks you to supply an object detection model. The documented route is to export YOLOv9 at 320x320 from the official repository using Docker; the tiny variant is the best fit for a 24 EU iGPU. Run it in an empty working directory, because the build writes the ONNX file into the current folder.
mkdir -p ~/yolo-export && cd ~/yolo-export
docker build . --build-arg MODEL_SIZE=t --build-arg IMG_SIZE=320 --output . -f- <<'EOF'
FROM python:3.11 AS build
RUN apt-get update && apt-get install --no-install-recommends -y cmake libgl1 && rm -rf /var/lib/apt/lists/*
COPY --from=ghcr.io/astral-sh/uv:0.10.4 /uv /bin/
WORKDIR /yolov9
ADD https://github.com/WongKinYiu/yolov9.git .
RUN uv pip install --system -r requirements.txt
RUN uv pip install --system onnx==1.18.0 onnxruntime onnx-simplifier==0.4.* onnxscript
ARG MODEL_SIZE
ARG IMG_SIZE
ADD https://github.com/WongKinYiu/yolov9/releases/download/v0.1/yolov9-${MODEL_SIZE}-converted.pt yolov9-${MODEL_SIZE}.pt
RUN sed -i "s/ckpt = torch.load(attempt_download(w), map_location='cpu')/ckpt = torch.load(attempt_download(w), map_location='cpu', weights_only=False)/g" models/experimental.py
RUN python3 export.py --weights ./yolov9-${MODEL_SIZE}.pt --imgsz ${IMG_SIZE} --simplify --include onnx
FROM scratch
ARG MODEL_SIZE
ARG IMG_SIZE
COPY --from=build /yolov9/yolov9-${MODEL_SIZE}.onnx /yolov9-${MODEL_SIZE}-${IMG_SIZE}.onnx
EOF
ls -lh yolov9-t-320.onnx
sudo mkdir -p /opt/frigate/config/model_cache
sudo cp yolov9-t-320.onnx /opt/frigate/config/model_cache/yolo.onnx
5Write config.yml: detector, decoding and cameras
Three blocks do the heavy lifting. detectors points OpenVINO at device GPU. model describes the 320x320 YOLOv9 input so the detector knows the tensor shape. ffmpeg.hwaccel_args uses the preset-vaapi preset, which is the recommended choice for 8th to 12th-gen Intel graphics and handles both H.264 and H.265 automatically. Detect runs on the camera's substream through go2rtc, while recording pulls the main stream directly from the camera, which is what Frigate expects for the record role.
mqtt:
enabled: false
detectors:
ov:
type: openvino
device: GPU
model:
model_type: yolo-generic
width: 320
height: 320
input_tensor: nchw
input_dtype: float
path: /config/model_cache/yolo.onnx
labelmap_path: /labelmap/coco-80.txt
ffmpeg:
hwaccel_args: preset-vaapi
go2rtc:
streams:
driveway:
- rtsp://viewer:[email protected]:554/Streaming/Channels/101
- "ffmpeg:driveway#audio=aac"
driveway_sub:
- rtsp://viewer:[email protected]:554/Streaming/Channels/102
cameras:
driveway:
ffmpeg:
inputs:
- path: rtsp://127.0.0.1:8554/driveway_sub
input_args: preset-rtsp-restream
roles:
- detect
- path: rtsp://viewer:[email protected]:554/Streaming/Channels/101
input_args: preset-rtsp-generic
roles:
- record
detect:
width: 1280
height: 720
objects:
track:
- person
- car
- dog
snapshots:
enabled: true
6Start Frigate and read the detector numbers
On first start Frigate creates its database and asks you to set an admin password in the web UI at port 8971. The logs state whether hardware acceleration was detected and whether the OpenVINO detector loaded; the System page then reports inference speed per detector. If inference time is longer than your camera frame interval, use fewer cameras on the same detector or move recording to a second detector definition.
cd /opt/frigate
docker compose up -d
docker compose logs -f frigate | grep -i -E "openvino|vaapi|detector|error"
docker compose exec frigate ls -l /dev/dri
7Set retention and close the front door
Frigate 0.18 splits recording retention into continuous, motion, alert and detection windows; keeping only motion video for a few days and alert clips for a month is the usual home setup. Then reduce the attack surface: publish only 8971, keep 5000 internal, and reach the UI remotely through Tailscale or a reverse proxy instead of exposing it to the internet.
record:
enabled: true
motion:
days: 3
alerts:
retain:
days: 30
mode: motion
detections:
retain:
days: 30
mode: motion
cd /opt/frigate
docker compose restart frigate
docker compose logs --tail 50 frigate