另外,我记录一下,2025年8月,尝试了 community script,发现ffmpeg跑不起来,视频流搞不定。
When installing ‘frigate’ lxc from the community script, I found the install script requires debian 11 lxc template.
But Proxmox 9 now only provides debian 12 in pveam available. so I can’t use the pveam cli tool to download the template.
And the lxc installer script only uses ‘pveam’ cli when the template is not found locally.
# the folder where templates are storedcd /var/lib/vz/template/cache# download this.wget http://download.proxmox.com/images/system/debian-11-standard_11.7-1_amd64.tar.zst
LXC Preparation
首先用这个 command 看看你的 PVE 能看到几张显卡:
for dev_path in /sys/class/drm/*; do dev_name=$(basename "$dev_path") if [[ "$dev_name" =~ ^(card|renderD)[0-9]+$ ]]; then # Double-check that the 'device' symlink exists to be safe if [ -L "$dev_path/device" ]; then full_dev_node="/dev/dri/$dev_name" pci_address=$(readlink "$dev_path/device" | awk -F'/' '{print $NF}') description=$(lspci -s "$pci_address") printf "Device Path: %s\n" "$full_dev_node" printf "PCI Address: %s\n" "$pci_address" printf "Description: %s\n" "$description" echo "" fi fidone
vim /etc/pve/lxc/<CTID>.conf# Content:arch: amd64cores: 2dev0: /dev/dri/card2,gid=44 # <- card{?}, here my iGPU is card2, so use card2dev1: /dev/dri/renderD129,gid=104 # <- renderD{?}, here my iGPU is renderD129, so use renderD129features: mount=cifs,nesting=1hostname: frigatememory: 4096net0: name=eth0,bridge=vmbr0,firewall=1,gw=192.168.1.1,hwaddr=<MAC>,ip=<CIDR>,type=vethostype: ubunturootfs: local-zfs-nvme:subvol-<CTID>-disk-0,size=16Gswap: 512tags: media
services: frigate: container_name: frigate privileged: true # this may not be necessary for all setups restart: unless-stopped # <- we will revisit it later stop_grace_period: 30s # allow enough time to shut down the various services image: ghcr.io/blakeblackshear/frigate:0.16.0 shm_size: 512mb # update for your cameras based on calculation above devices: # - /dev/bus/usb:/dev/bus/usb # Passes the USB Coral, needs to be modified for other versions # - /dev/apex_0:/dev/apex_0 # Passes a PCIe Coral, follow driver instructions here https://coral.ai/docs/m2/get-started/#2a-on-linux # - /dev/video11:/dev/video11 # For Raspberry Pi 4B # - /dev/dri/renderD128:/dev/dri/renderD128 # Normally, this is the one to use. - /dev/dri/renderD129:/dev/dri/renderD129 # But for my case, I need to use this one. # -/dev/dri:/dev/dri # this is the last resort, map all devs volumes: - /etc/localtime:/etc/localtime:ro - /root/frigate/config:/config - /root/frigate/storage:/media/frigate - type: tmpfs target: /tmp/cache tmpfs: size: 1000000000 ports: - 8971:8971 - 5000:5000 # Internal unauthenticated access. Expose carefully. - 8554:8554 # RTSP feeds - 8555:8555/tcp # WebRTC over tcp - 8555:8555/udp # WebRTC over udpnetworks: {}
mqtt: # <- do this if you use Frigate<>HAOS integration. host: <your_home_assistant_ip_or_fqdn> user: frigate password: <pass> port: 1883 topic_prefix: frigate client_id: frigate############################## Global Detection Settings ##############################detect: enabled: trueobjects: track: - person - bear - bird - cat - dog - car filters: car: min_score: 0.55 threshold: 0.76audio: enabled: true min_volume: 200 listen: - babbling - crying - scream########################### Global Record Settings ###########################record: enabled: truesnapshots: enabled: truereview: alerts: labels: - crying - scream - yell - cough - mouse - bear############ Streams ############go2rtc: streams: driveway_sd: - rtsp://haha:heihei@<ip_cam>:554/stream2 - ffmpeg:driveway_sd#audio=aac#hardware############ Cameras ############cameras: driveway: enabled: true ffmpeg: inputs: - path: rtsp://127.0.0.1:8554/driveway_sd?video&audio input_args: preset-rtsp-restream roles: - detect - audio - path: rtsp://127.0.0.1:8554/driveway_hd?video&audio input_args: preset-rtsp-restream roles: - record output_args: record: preset-record-generic-audio-aac review: alerts: labels: - bear - dog - cat - mouse motion: mask: # <- usually those ones are created from the UI, but is persisted in yaml and can be reused across Frigate versions. - 0.357,0,0,0,0,0.049,0.357,0.057 - 0.525,0.822,0.564,0.819,0.568,0.896,0.526,0.901# Example of a dummy camera feed which is actually a video clip.# test:# enabled: false# ffmpeg:# #hwaccel_args: preset-vaapi# inputs:# - path: /media/frigate/exports/driveway_npcy9r.mp4# input_args: -re -stream_loop -1 -fflags +genpts# roles:# - detect# - rtmp# detect:# height: 1080# width: 1920# fps: 5# audio:# enabled: false# objects:# track:# - bear################################### Detector and Models and FFmpeg ###################################detectors: ov: type: openvino device: GPU # <- this and the 'openvino' type will tell Frigate to use iGPU for detection. model_path: /openvino-model/ssdlite_mobilenet_v2.xml # <- note that this is changed from 0.14.0, if model_path not exist, Frigate can crash and your container will likely keep restarting.model: width: 300 height: 300 input_tensor: nhwc input_pixel_format: bgr labelmap_path: /openvino-model/coco_91cl_bkgr.txtffmpeg: hwaccel_args: preset-intel-qsv-h264 # <- tell Frigate to use iGPU (qsv) for h264 decoding (actually if your cam res not too high, this is not really needed.)version: 0.16-0 # <- Easy to miss this one, if you copy config from Frigate of older versions, do check this one.
Mount external storage for video clips
LXC 通常还是比较轻量的好,而且 records 本身实际上很多时候并不像 config 那样一点都不能错。所以大概率还是要存在一个 remote storage 上面的。
假定我们 mount 一个 NFS。这里其实有两个方案:
直接在 Docker compose YAML 里面定义一个 volume with driver type: nfs.
fstab 挂载,然后手动改 systemd config 来保证 mount 在 container 启动前完成。
个人认为这个方式,虽然看起来更复杂一些,但是实际上可操作性更强。
homelab 嘛,经常需要查错的,这个时候每一步单独查错时候的可复制性和透明度就挺重要的。
NFS mount
In your LXC shell (I’m using Ubuntu 24.04):
apt install nfs-commonmkdir /mnt/frigatevim /etc/fstab# Example Content (assume your NFS server exports storage at /mnt/tank/nvr/frigate):# UNCONFIGURED FSTAB FOR BASE SYSTEM<YOUR_NFS_SERVER_IP>:/mnt/tank/nvr/frigate /mnt/frigate nfs defaults,_netdev,auto 0 0mount -a# /mnt/frigate should be ready to use.
Use Systemd to manage the docker compose dependency on NFS mount
# vim /etc/systemd/system/frigate-docker.service[Unit]Description=Frigate Docker Compose Service# v: this 'mnt-frigate' is auto generated from the mount at '/mnt/frigate'Requires=mnt-frigate.mountAfter=mnt-frigate.mount network-online.target[Service]# Location of the docker compose file. I'm using dockge and by default the yaml is stored here:WorkingDirectory=/opt/stacks/frigate# v: do not use `-d` here.ExecStart=/usr/bin/docker compose upExecStop=/usr/bin/docker compose downRestart=alwaysRestartSec=5s[Install]WantedBy=multi-user.target
NOTE
这里有一个坑。如果 Restart 设定是 on-failure。就会导致 Frigate 在 UI 里面更改
config 后的 save and restart frigate 无法正常重启 Frigate。所以这里一定要用 Always。
# cat /etc/systemd/system/jellyfin-docker.service[Unit]Description=Jellyfin Docker Compose Service# 'mnt-media' is auto generated from the mount at '/mnt/media'Requires=mnt-media.mountAfter=mnt-media.mount network-online.target[Service]# Location of the docker compose file. I'm using dockge and by default the yaml is stored here:WorkingDirectory=/opt/stacks/jellyfin# v: do not use `-d` here.ExecStart=/usr/bin/docker compose upExecStop=/usr/bin/docker compose downRestart=on-failureRestartSec=5s[Install]WantedBy=multi-user.target