I’ve been careening down the road towards a “proper” camera management system for some time now. I’ve tried most things, and so far they’ve all fallen short. Either they’re too heavy, too feature-poor, or too complex for my needs. It’s a little like Goldilocks but with pixels and RTSP streams instead of porridge.

This is a blog about getting Frigate working on my local network. Tradeoffs, ugly bits, and automation included. I’m sure I’ll look back on it in a year or two and have regrets. But for now, let’s take a look at what’s out there.

The Equipment

Hardware: HP EliteDesk Small Form Factor, Google Coral TPU Price: Free! (though you can pick these up for maybe $40 NZD total)

I’m specifically choosing this setup because with an i7 and 16GB RAM, it’s beefy enough to run Frigate properly. It’s also small enough to fit into the space I have in my rental. I only have a couple cameras running right now, if this ever hits a proper limit, I’ll switch out to something larger.

The Coral TPU is the secret sauce here. It offloads object detection from the CPU entirely, meaning Frigate barely touches the i7 for inference. Without it, you’re burning CPU cycles on every frame. With it, detection runs at ~10ms per frame.

The Goldilocks Zone

BlueIris

For the most part, I liked BlueIris. Except for it being Windows only. And CPU-intensive (especially when you throw in many streams). It’s a monolithic Windows app. It’s not there for efficiency; it’s mature and highly configurable. Fine if you’re a corporate.

Running this as a Windows VM (because I’m not sacrificing an entire PC to run Windows just for BlueIris) was the breaking point for me.

ZoneMinder

ZoneMinder is… complicated. I like it, but it’s esoteric, uses older UX conventions and doesn’t have as large a feature set. It’s no slouch, supporting multi-camera, events, and analysis, but its ecosystem just isn’t as modern or as easily plug-and-play as some others.

Resource scale really counts here. The more cameras, the more heft is required. Given it uses Linux + LAMP, I’d like to give it more love, but not enough to push it over the edge.

random cloud provider

Definitely not. Sure, this is much lighter on my resources, but it’s also much heavier on my privacy loss, and it’s only a matter of time until each cloud provider is hacked and those embarrassing videos of me dancing in my underwear get leaked. You know the ones. www.patreon.com/youwish

Frigate - Just Right

Light (relative to the others) - especially when I pair it with this lovely little Coral TPU. There are efficiencies here, mainly because it’s aimed squarely at event recording instead of constant, process-bloating continuous processing.

We get MQTT, Home Assistant and containers. This is great since most of my homelab runs on containers (or TrueNAS), and Home Assistant is my very next target after Frigate works flawlessly.

And it runs on Linux (well, anywhere really - my first test I ran on a TrueNAS Scale box, but it felt like overkill. Plus, I like my services to be logically separated)

Ubuntu

Arguably, the easiest step is to download and flash Ubuntu server to a flash disk. Hey, remember when downloads were slow? Yeah, me too. I still have mild trauma from an 8-hour download timing out at 95%. Yeah. It took 3.5 minutes to download the Ubuntu Server ISO. Yikes.

Use whatever method you want to flash the disk. If you’re feeling particularly sadistic, you’re welcome to use dd like me to run it. Ubuntu has an extensive guide here.

But I don’t want to plug in a keyboard and monitor, click through an installer, then SSH in and configure everything by hand. I want to plug in a USB, power it on, and come back to a working NVR. Enter: autoinstall.

Configuring the Repack

The hardest part is getting the repack to give me what I want. Xorriso makes this easier, but we’re still going to have to do some fiddling, mainly with user-data and getting curtin to play nicely.

One gotcha that cost me two failed installs: cloud-init’s NoCloud datasource needs a full file:///cdrom/autoinstall/ URL in the GRUB config, not a bare path. Every tutorial I found got this wrong.

Once that was solved (attempt #5), booting up Ubuntu was a breeze.

Frigate Config

I confess I cheated a little here. I had a previous trial run of Frigate running on my TrueNAS box, so it was pretty simple to scp it out and flick it over after startup. I might rework this so the frigate config is pulled in automatically from a repo, but that’s for the next iteration.

It’s far simpler than you think to get the YAML right - the biggest pain was getting the correct URL out of the Tapo cameras, and you’ll find yourself reading a lot of bugs/posts like this.

Getting Docker up and running also took a bit of doing - but not in the way I’d have expected. Embarrassingly, this was just a simple sequencing issue where I tried to join the new frigate user to the Docker group before the group existed:

command_0: SUCCESS: curtin in-target -- bash -c 'curl -fsSL https://get.docker.com |sh'
command_1: FAIL: curtin in-target -- usermod -aG docker frigate (exit code 6)

Again, a simple fix: move provisioning to a first-boot script. Subiquity’s late-commands run inside a chroot via curtin, which means stale group databases, no running services, and any failure aborts the entire OS install. A first-boot systemd oneshot avoids all of that — and if it fails, you can still SSH in and debug.

And just like that, Ubuntu is up, and after a reboot, Docker returns exactly what it should:

frigate@frigate:~$ docker ps
CONTAINER ID   IMAGE                                    STATUS                   NAMES
de815bfd6471   ghcr.io/blakeblackshear/frigate:stable   Up 5 minutes (healthy)   frigate

Sweet, sweet bliss, my Frigate now boots up and looks pretty. There’s only one camera configured, but the next step is to get my Coral TPU working for detection. Onwards and upwards! Total time from bare metal to a working NVR? About an hour and a half, most of that waiting for installs to run.

Next Up: Configuring Frigate face, numberplate, and other detection with Coral TPU!