Frigate NVR logo
|

How to Install Frigate NVR with Coral USB TPU in a Docker VM (Proxmox Guide)

In this guide, I’ll walk you through setting up Frigate NVR using Docker inside a virtual machine,
with hardware acceleration via a passed-through Coral USB TPU. This setup is ideal for homelab
enthusiasts looking to offload object detection tasks and maximize performance on their local
servers.

Prerequisites

  • A working VM host (I’m using Proxmox in this example)
  • A Google Coral USB TPU for hardware-accelerated object detection
  • A virtual machine with Docker and Docker Compose installed
  • Storage configured for Frigate recordings (e.g., NFS share, local disk)
  • Either Portainer or access to the Docker CLI

Host Configuration (USB Passthrough)

To enable object detection using the Coral TPU, you’ll need to pass the USB device through to your
virtual machine.

For Proxmox users:

  1. Plug the Coral TPU into your host machine.
  2. In the Proxmox web interface, go to your VM:
    • Hardware > Add > USB Device
  3. Select the Coral TPU from the list of available USB device
Proxmox add USB device

Note: If it says “Unplugged,” don’t worry, it usually means the device is already passed through
and in use by the VM.

Docker Deployment (Frigate with Coral TPU)

Once the Coral USB TPU is passed through, it?s time to deploy Frigate.

Option 1: Using Portainer

  1. Open Portainer and go to Stacks
  2. Click Add Stack
  3. Name your stack (e.g., frigate)
  4. Paste your docker-compose configuration

Option 2: Using the Docker CLI

  1. SSH into your Docker VM
  2. Create a new folder for Frigate, for example:
    mkdir -p ~/frigate
    cd ~/frigate
  3. Use your preferred text editor to create the compose file:
    nano frigate.yml
  4. Paste the Frigate Docker Compose code
version: "3.9"
services:
  frigate:
    image: ghcr.io/blakeblackshear/frigate:stable
    environment:
      - FRIGATE_RTSP_PASSWORD=<create secret>         <-- change this
    container_name: frigate
    privileged: true
    devices:
      - /dev/bus/usb:/dev/bus/usb                     #TPU
    restart: unless-stopped
    shm_size: "2048mb" 
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - <config source>:/config                       <-- change this
      - <media storage>:/media/frigate                <-- change this
      - type: 
        target: /tmp/cache
        tmpfs:
          size: 2000000000
    ports:
      - "5000:5000" #Friagte web port
      - "1935:1935" # RTMP feeds
      - "8554:8554" #Detection restream URL
      - "8555:8555/tcp" # WebRTC over tcp
      - "8555:8555/udp" # WebRTC over udp

Don’t forget to adjust the configuration to match your environment, such as your volume paths,
network settings, and USB device paths.

Deploying the Stack

  • Portainer: Click Deploy the Stack
  • CLI: Run the following command in the directory where frigate.yml is located:
    • docker compose -f frigate.yml up -d

Frigate Configuration

After the container is running, locate the Frigate configuration file (config.yaml) within your mapped
volume or project folder.
Edit config.yaml to define:

  • Cameras and their input sources
  • Detection parameters
  • Storage locations
  • Object detection zones
  • Motion settings

A part of my code:

logger:
  logs:
    frigate.record.maintainer: debug

##Choose MQTT server##
mqtt:
  host: 
  user: 
  password: 

ffmpeg:
  global_args: -hide_banner -loglevel warning -threads 2
  #hwaccel_args: preset-vaapi
  input_args: preset-rtsp-generic
  output_args:
    detect: -threads 2 -f rawvideo -pix_fmt yuv420p
    record: preset-record-generic-audio-copy
  retry_interval: 10

##########################################################################
#########################Go2RTC cams######################################
go2rtc:
  streams:
    Garden:
      - rtsp://<user:pass>@<IP>:554//h265Preview_01_main
    Garden-sub:
      - rtsp://<user:pass>@<IP>:554//h264Preview_01_sub
    Doorbel:
      - rtsp://<user:pass>@<IP>:554//h264Preview_01_main#audio=pcm#audio=volume
    Doorbel-sub:
      - rtsp://<user:pass>@<IP>:554//h264Preview_01_sub#audio=pcm#audio=volume
    ffmpeg:
      bin: ffmpeg
      volume: -af "volume=30dB"
      input_args: -avoid_negative_ts make_zero -fflags +genpts+discardcorrupt -flags
        low_delay -strict experimental -analyzeduration 1000M -probesize 1000M -timeout
        5000000
      output_args:
      record: -f segment -segment_time 10 -segment_format mp4 -reset_timestamps 1
        -strftime 1 -c copy -tag:v hvc1 -c:a aac
##########################################################################

birdseye:
  enabled: true
  mode: continuous

##########################################################################
######################CONFIG WIDE VARIABLES###############################
##########################################################################
snapshots:
  enabled: true
  timestamp: false
  bounding_box: true
  retain:
    default: 2
record:
  enabled: true
  retain:
    days: 2
    mode: motion
  alerts:
    retain:
      days: 4
      mode: motion
    pre_capture: 7
  detections:
    retain:
      days: 4
      mode: motion
    pre_capture: 7
detect:
  fps: 5
  enabled: true # <---- disable detection until you have a working camera feed
  min_initialized: 2
  max_disappeared: 25
objects:
  track:
    - person
    
##########################################################################
######################SET CORAL TPU DETECTOR##############################
##########################################################################
detectors:
  coral:
    type: edgetpu
    device: usb


cameras:
  Garden:
    ffmpeg:
      inputs:
        - path: rtsp://127.0.0.1:8554/Garden
          roles:
            - record
        - path: rtsp://127.0.0.1:8554/Garden-sub
          roles:
            - detect
    live:
      stream_name: Garden
    detect:
      width: 640
      height: 360
    motion:
      threshold: 40
      contour_area: 30
      improve_contrast: true
    zones: {}
    
  Doorbel:
    ffmpeg:
      inputs:
        - path: rtsp://127.0.0.1:8554/Doorbel
          roles:
            - record
        - path: rtsp://127.0.0.1:8554/Doorbel-sub
          roles:
            - detect
      output_args:
        record: preset-record-generic-audio-copy
    live:
      stream_name: Doorbel
    motion:
      threshold: 29
      contour_area: 12
      improve_contrast: true

Refer to the official Frigate documentation for detailed configuration options.

Conclusion

You’ve now installed Frigate NVR with a Coral USB TPU passed through to a Docker VM in your
homelab environment. With this setup, you’ll benefit from efficient, real-time object detection and
centralized camera recording, all while keeping your infrastructure self-hosted and under your
control.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *