2022-09-09 - v3 Edit: Updated to reflect final working LXC->Docker->Frigate approach. Added notes on frigate config, camera streams and frigate storage.
Background:
I had a working setup on ESXI, but alas, no PCIE slot and thus no way to pass through the USB google coral in such a way that the VM will recognize it.
(See this thread here for more on that struggle… )
It was suggested that it could be done via PROXMOX, so after looking at many different threads, I pieced together the below set of instructions. I have been running this for a few months now and it seems reasonably stable with a frigate inference speed of between 8-10.
Known Issues:
- After a reboot, the Coral sometimes changes from one USB port or bus to another, which requires editing the configuration file for the frigate LXC, and then restarting the frigate LXC.
- The docker LXC (running frigate) is priviledged. Others have posted improvements to get the LXC to run as unpriviledged but I havent tried this yet. I will update the instructions if/when I get it working.
Part 1 - Installing ProxMox 7.1
-
Download Proxmox 7.0 ISO
-
Download USB Imager
-
Format the USB Stick ( Very important)
If you forget to do this, you can use these steps to clean the USB drive. -
Install ProxMox
Dont choose ZFS unless you have 32Gb+ RAM. Otherwise just accept defaults
The licensing pop up is normal. -
Apply Updates
Go to updates, refresh, then click upgrade.
Its normal that some will fail as you dont have the enterprise license
Leave update window open and answer any questions that pop up
Part 2 - Installing Home Assistant
-
Watch this for reference:
https://www.youtube.com/watch?v=9sKpOODLJHs -
Create new VM
Under OS, choose “Do not use any media”
Under System, for BIOS choose “OVMF (UEFI)” and for local storage choose “local-lvm”. Also ensure you uncheck “pre-enroll keys”.
Accept defaults for everything else (unless you want to mess with # of CPUs or memory etc). -
Go to the hardware tab, find the “Hard Disk (scsi0)”, then click “Detach”, then “Remove”.
-
Get URL for KVM/ProxMox here:
Alternative - Home Assistant
copy the download URL to the .qcow2 file -
Open the command prompt for proxmox (not for the VM itself). Run the below commands to get the home assistant .qcow2 file.
wget TheQCOW2DownloadURL
-
Decompress the file (From the same command line):
Xz -d -v (yourfilename).qcow2.xz
-
Import the file into the VM (From the same command line):
qm importdisk 104 ./haos_ova–7.1.qcow2 local-lvm -–format qcow2
*Note the VM # and file name to use in the statement
-
From ProxMox UI, go back into VM to attach this new disk to your VM
Double click on the unused disk
Check SSD emulation, and add the disk -
Update VM boot options
Set SCSI drive to first and enable it -
Start VM
-
Open VM CLI, note the IP address displayed
Part 3 - Configure Home Assistant
- After you log in, go to profile (bottom left), then enable advanced mode
- Install file editor from add on store
- Install mosquitto mqtt broker
- Open the users area and create a user/password entry for frigate to use. (Frigate will use it to connect to Mosquitto MQTT)
Part 4 - Install Docker in LXC Container
-
Watch this for reference:
https://www.youtube.com/watch?v=gXuLiglJceY -
Download Turnkey-core template
- From console, run “pveam update” to refresh the list of templates
- Go to proxmox storage (“local (pve)”) and go to “CT Templates”
- Search for “Core”, select “turnkey-core” and hit “download”
I used 16.1.1 (“Debian-10-turnkey-core_16.1-1_amd64.tar.gz”) - Click “CT Templates” again and verify it shows up in your list
-
Create LXC container
- Click “Create CT”
- General tab
- Hostname: “docker”
- Set password and note it for later user
- Uncheck “unpriviledged container” (make it privileged)
(I think the container needs to be “priviledged” for the USB to pass through correctly. Someone correct me if Im wrong here)
- Template tab
- Storage: local
- Template: choose the turnkey-core template
- Root Disk tab
- 32 GB (or whatever you want)
- CPU tab
- Cores: 1 (or whatever you want)
- Memory tab:
- Memory: 2125 (or whatever you want)
- Network tab:
- IPv4: DHCP
- Accept all other defaults
- Click finish to initialize
-
Configure the new Container
-
Options->Features
- Enable “keyctl”
- Enable “Nesting”
-
Install Debian Turnkey Core
1. Start the container
2. Open console for the container, and login with root + password noted earlier
3. Skip first 2 prompts, then click “Install” to install security updates
4. Once finished, CTRL+C to get out
5. Update & upgrade debian
1.>apt update
2.>apt upgrade
-
Install Docker in the LXC Container
-
Review this for reference: Install Docker Engine on Debian | Docker Docs
-
And review this: Setup and Install Dock... | The Homelab Wiki
-
Run the below commands (Step 1, 2 and 3 from the “Set up the repository” section here: Install Docker Engine on Debian | Docker Docs
(Remove “sudo” from commands since you are already logged in as root)- Step 1:
apt-get install \ ca-certificates \ curl \ gnupg \ lsb-release
- Step 2
curl -fsSL https://download.docker.com/linux/debian/gpg gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
- Step 3:
echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \ $(lsb_release -cs) stable" tee /etc/apt/sources.list.d/docker.list > /dev/null
- Step 1:
-
-
Install docker engine.
apt-get update apt-get install docker-ce docker-ce-cli containerd.io
-
Verify Docker is running:
Systemctl status docker
-
Install Portainer (to simplify management of docker)
- Review this page here: Installing Docker and ... | The Homelab Wiki
- Run this code to install portainer on port 9000 and 8000
docker run -d \ --name="portainer" \ --restart on-failure \ -p 9000:9000 \ -p 8000:8000 \ -v /var/run/docker.sock:/var/run/docker.sock \ -v portainer_data:/data \ portainer/portainer-ce:latest
- Confirm container’s IP
ip addr
- Open your browser and log in to portainer:
http://yourcontanieripaddress:9000/ - Log in as “admin” and set the password
Part 5 - Installing Frigate in Docker using Portainer
-
Review this for reference:
https://www.youtube.com/watch?v=qfchptEzqdo&t=727s -
In Docker LXC, Go to /home folder, create a frigate folder, and create a config.yml file (/home/frigate/config.yml)
vi config.yml
(esc+i for insert, esc+o for newline, :q! For quit, :wq! For write/quit)Create your frigate configuration (your on your own here)
detectors: cpu1: type: cpu
-
In portainer, create a new stack called “homeautomation”:
#######################FRIGATE
frigate:
__container_name: frigate
__image: blakeblackshear/frigate:stable-amd64
__restart: always
__devices:
___- /dev/bus/usb:/dev/bus/usb
__volumes:
___- /etc/localtime:/etc/localtime
___- /home/frigate/config.yml:/config/config.yml:ro
__ports:
___- 5000:5000
___- 1935:1935
__environment:
___FRIGATE_RTSP_PASSWORD: "topsecretfrigatepassword"
- Start the container and confirm you can access frigate on port 5000
http://yourcontaineripaddress:5000/ - Confirm frigate is working using basic CPU detection
Part 6 - Configure LXC to pass through the Coral
-
In the host, verify which USB bus the coral is on. Run “lsusb” to confirm.
You will need to pass the entire bus through. For me it was bus 002.
Also note if it lists “2.0 root hub” or “3.0 root hub”. You want to ensure the coral is plugged in to a USB 3.0 root hub if you want the best inference speed -
In the host, navigate to /etc/pve/lxc and edit the config file for your LXC #
vi 101.conf
Add the higlighted bit below to your configuration:
(everything below the “swap: 512”)arch: amd64 cores: 1 features: keyctl=1,nesting=1 hostname: docker memory: 2125 net0: name=eth0,bridge=vmbr0,firewall=1,hwaddr=22:FA:5D:3E:BD:D9,ip=dhcp,type=veth ostype: debian rootfs: local-lvm:vm-101-disk-1,size=32G swap: 512 lxc.cgroup2.devices.allow: c 226:0 rwm lxc.cgroup2.devices.allow: c 226:128 rwm lxc.cgroup2.devices.allow: c 29:0 rwm lxc.cgroup2.devices.allow: c 189:* rwm lxc.apparmor.profile: unconfined lxc.cgroup2.devices.allow: a lxc.mount.entry: /dev/dri/renderD128 dev/dri/renderD128 none bind,optional,create=file 0, 0 lxc.mount.entry: /dev/bus/usb/002 dev/bus/usb/002 none bind,optional,create=dir 0, 0 lxc.cap.drop: lxc.mount.auto: cgroup:rw
Note I used cgroup2. You may need to use cgroup.
(Not sure how to tell which control group is required) -
If it wont start, reboot the host (not the guest)
-
Ensure you created the container earlier as a privileged container (uncheck unpriviledged)
- If you made a mistake, you can fix it by doing a backup then restore of the LXC
-
Log in to the LXC and confirm that the Coral USB is passed through
(No point in going any further if it isnnt detected!)-
apt-get install usbutils
-
lsusb
-
-
Update frigate’s config.yml to Switch to coral
detectors: _coral: __type: edgetpu __device: usb
-
Check log file (using portainer) for frigate and confirm its working
Part 7 - Take a snapshot!
- This is a good time to take a snapshot within ProxMox.
Go to the Home Assistant VM, click snapshots and take a snapshot.
Part 8 - Install Home assistant Frigate add on and integration
-
From add on store, add this repository:
https://github.com/blakeblackshear/frigate-hass-addons
-
Add the “Frigate NVR Proxy” add-on
-
Configure the add on (Enter the IP address and port of frigate)
eg 192.168.1.210:5000
-
Set to show in sidebar
-
Start Frigate
-
Confirm you can see frigate in the side bar and it works
-
Celebrate
Appendix A - Notes on Frigate and Camera Setup
Its mentioned in the frigate documentation that Frigate doesn’t need a high res stream to perform detection, and there are diminishing returns when passing it a higher resolution stream or frame rate.
If your camera supports multiple streams, what I have found works well is to:
- Create two rtsp steams on the camera
- 1 high resolution & high frame rate (for NVR recording)
- 1 low resolution & low frame rate (for detection, and for displaying in home assistant)
- In home assistant, use the “generic camera” integration to view the low res stream directly in home assistant. eg for HikVision:
- Still Image URL: http://192.168.1.200/ISAPI/Streaming/Channels/2/picture
- Stream URL: rtsp://frigateuser:[email protected]:554/Streaming/Channels/102
- Configure 2 inputs in frigate (one for record, one for detect)
- Disable RTMP in frigate (Theres no point in re-streaming the feed to home assistant. There will be less lag if we have home assistant pull directly from the camera).
- Frigate Config Example:
rtmp:
enabled: false
cameras:
driveway_cam2:
ffmpeg:
inputs:
- path: rtsp://frigateuser:[email protected]:554/Streaming/Channels/101
roles:
- record
- path: rtsp://frigateuser:[email protected]:554/Streaming/Channels/102
roles:
- detect
output_args:
detect: -f rawvideo -pix_fmt yuv420p
record: -f segment -segment_time 60 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c copy -c:a aac
detect:
Appendix B - Camera Selection
FWIW. I started out with the Unifi G3 Flex camera, and upgraded to the HikVision DS-2CD2347G2-LU.
I am extremely happy with this camera’s night vision performance. It truly does provide full color video under very low light conditions.
low light conditions.
Appendix C - Frigate Recording Storage
In terms of storage for frigate camera recordings etc, I have found it useful to pass through a ZFS mount point. This way the recordings can be easily blown away without affecting frigate, and vice versa. Also it keeps the LXC image smaller, which simplifies snapshots, backups and restores.
Unfortunately I lost my notes on the setup, but I think it was roughly along the lines of the below:
- From proxmox “DataCenter”, Go to storage, and create a ZFS filesystem on a free drive.
- From proxmox docker LXC, Go to resources => Add => Mount Point. For “Storage”, choose your zfs file system, and enter a size in the “Disk Size” field that is smaller than the remaining available space. For the path, enter something like “/mnt/frigatedata”
- In portainer, ensure the mount is passed through to the container running frigate by editing the stack to include this: “/mnt/frigatedata:/media/frigate”. So effectively Proxmox is passing the ZFS partition through to the LXC as “/mnt/frigatedata”, then docker is passing it through to the container as “/media/frigate” (which is the default location used by frigate to store recordings).
#######################FRIGATE
frigate:
container_name: frigate
image: blakeblackshear/frigate:stable-amd64
restart: always
devices:
- /dev/bus/usb:/dev/bus/usb
volumes:
- /etc/localtime:/etc/localtime
- /home/frigate/config.yml:/config/config.yml:ro
- /mnt/frigatedata:/media/frigate
- /run:/tmp/cache
ports:
- 5000:5000
- 1935:1935
environment:
FRIGATE_RTSP_PASSWORD: "topsecretfrigatepassword"
Appendix D - Results
So far I have caught 1 night walker with this setup. The below happened at 2 am but with the hikvision it almost looks like daytime. The night-walker was detected just before he got close to the cars and immediately persuaded to take his shenanigans elsewhere.
DIY Home Security vs Night Crawler 2022-04-24 - YouTube