I have been using Frigate for a couple years now as my NVR and for camera alerting. It’s been great to use but also frustrating at times to set up. It’s gotten better over the years, but it’s still not user-friendly and definitely not something you should set up for your parents or grandparents.

I used to run Frigate in Unraid, but I recently dropped it in favor of TrueNAS for performance reasons. With this, an opportunity arose to migrate Frigate into my ProxMox virtual environment. The benefit of doing this would mean I can easily back up my frigate environment, I can migrate it to another machine if it fails, and I can easily test configs without worrying about losing my current config.

The easiest way to run Frigate is via Proxmox Helper Scripts as an LXC container. However, I recommend against that for several reasons.

  1. Upgrading Frigate isn’t easy. Sure, there’s an ‘upgrade’ command that you can run, but you don’t really have much control beyond that.
  2. Altering the config isn’t as straightforward.
  3. For some reason, detect performance isn’t as great as running in Docker mode.

Instead, what I recommend doing is running Frigate in a Docker container instead. This gives you several benefits:

  1. You can easily switch back and forth between versions with Docker + Compose
  2. Using Compose, you can customize the installation a bit easier
  3. You can still take advantage of GPU resource sharing by running it in an LXC

First, I use a Coral TPU unit installed in my M2 Wifi PCI slot. So, drivers need to be installed on the PVE Host. On the PVM host console, run the following:

1
2
3
4
5
echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" | tee /etc/apt/sources.list.d/coral-edgetpu.list

curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -

apt-get update

Then install pve-headers and the PCIE driver and TPU runtime packages

1
2
3
apt install pve-headers-$(uname -r)
 
apt-get install gasket-dkms libedgetpu1-std

Reboot the node (The entire system), then run:

1
lspci -nn | grep 089a

It should return something like this:

1
3d:00.0 System peripheral [0880]: Global Unichip Corp. Coral Edge TPU [1ac1:089a]

Then verify that the driver loaded:

1
ls /dev/apex_0

That should return:

1
/dev/apex_0

The latest proxmox kernel breaks many of the coral drivers. To fix:

1
2
3
4
apt remove gasket-dkms
apt install git
apt install devscripts
apt install dh-dkms

Then navigate to home and load the gasket driver

1
2
3
4
5
6
7
cd /home

git clone https://github.com/google/gasket-driver.git
cd gasket-driver/
debuild -us -uc -tc -b
cd ..
dpkg -i gasket-dkms_1.0-18_all.deb

Perform all updates again

1
apt update && apt upgrade

Then run ls /dev/apex_0 again and verify that it exists

Create Docker Image

Next, you’ll need to create a privileged LXC docker, and install portainer. (here’s where I did use Proxmox Helper Scripts):

bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/ct/docker.sh)"

In the host console, edit the hardware passthrough details:

1
nano /etc/pve/nodes/(NODE-NAME)/lxc/(CONTAINER-ID ex. "100").conf

Add in the following items to the config (make sure nothing is duplicated)

1
2
3
4
5
6
7
8
9
lxc.cgroup2.devices.allow: c 226:0 rwm #igpu
lxc.cgroup2.devices.allow: c 226:128 rwm #igpu
lxc.cgroup2.devices.allow: c 29:0 rwm #coral
lxc.cgroup2.devices.allow: c 189:* rwm #coral
lxc.cgroup2.devices.allow: a
lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file 0, 0 #igpu
lxc.mount.entry: /dev/apex_0 dev/apex_0 none bind,optional,create=file 0, 0 #coral
lxc.cap.drop:
lxc.mount.auto: cgroup:rw

In portainer, create a frigate stack using the following docker compose:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
services:
  frigate:
    container_name: frigate
    privileged: true # this may not be necessary for all setups
    restart: unless-stopped
    image: ghcr.io/blakeblackshear/frigate:stable
    shm_size: "1024mb" # update for your cameras based on calculation above
    devices:
      - /dev/apex_0:/dev/apex_0 # Passes a PCIe Coral
      - /dev/dri/renderD128:/dev/dri/renderD128 # For intel hwaccel, needs to be updated for your hardware
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /opt/frigate/config:/config
      - /mnt/frigate:/media/frigate # here's where you want to point to where you want to save recordings
      - type: tmpfs # Optional: 1GB of memory, reduces SSD/SD Card wear
        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 udp
    # environment:
      # FRIGATE_RTSP_PASSWORD: "password"

Start it up and go to the web console at port 5000 to make sure the TPU and GPU are detected. Good to go!