DockerSelf-HostingAI

Frigate NVR with Docker: local AI camera detection (Linux, Windows, Mac)

Before you start

  • 20 min read

Boxes marked Run in terminal are what you type; plain text explains why. Check what you need first

What you get in one minute#

Frigate is a free, self-hosted network video recorder (NVR) that watches your IP cameras, runs AI object detection on your own hardware, and records only what matters, such as a person at the door.

Frigate NVR official logo

Logo: the official Frigate project (github.com/blakeblackshear/frigate), used unchanged to identify the software. The Frigate name and logo are trademarks of Frigate, Inc.

It suits a home or small office that wants camera alerts without a cloud subscription. The docs say core use needs no internet: video, detection and recordings stay on your server.

WhatValue (official docs and releases, read October 2026)
Current versionFrigate 0.18.2, released 15 October 2026 (a maintenance release with security fixes)
Image to pinghcr.io/blakeblackshear/frigate:0.18.2 (checked on the registry)
Time neededAbout 45 minutes with one camera (our estimate, not measured)
RAM and diskNo single figure in the docs; shm-size per camera is below, disk depends on cameras and retention
Ports8971 (login-protected UI), 8554 (RTSP restream), 8555 (WebRTC), 5000 (no login: keep private)
LicenceMIT for the code. The name and logo are trademarks
Official docsdocs.frigate.video and the repository

At a glance:

  • What it is: one Docker container with a web UI, camera restreaming, motion detection, an AI detector and a recorder.
  • You need a detector: an Intel GPU or NPU (OpenVINO), an NVIDIA GPU, a Google Coral or another accelerator. The CPU detector is "not recommended for general use".
  • Linux is the supported server: bare-metal Debian-based Linux with Docker. Windows is not officially supported; macOS on Apple Silicon is documented.
  • Set shm_size: Docker's 64 MB default is too small. The docs say about 210 MB for 2 cameras at 720p.
  • Pin the tag: 0.18.2. Version 0.18 changed several settings, so back up your config first.
  • Privacy: keep cameras off the internet and Frigate off your router's port forwards. Optional features (Frigate+, cloud AI, push alerts) do contact outside services.

How it fits together#

Cameras send video to Frigate over your local network. Frigate checks for motion, asks the detector what moved, and records. You open the web UI on port 8971, or behind HTTPS.

Two lanes: IP cameras send RTSP video to Frigate, which finds motion, asks the AI detector (OpenVINO, Coral or NVIDIA) what moved, records and saves to the host folders; you reach the web UI on port 8971 through Caddy or Traefik over HTTPS

Drawn for this guide from the official docs. The HTTPS route (dashed) is optional.

Before you start#

You need a Linux machine that stays on, Docker with Compose, an RTSP IP camera, and a detector.

Linux server: Docker Engine and Compose. The docs say an Intel CPU with AVX and AVX2 that runs Debian works fine, on bare metal; a virtual machine is "not recommended". A mini PC with two network ports suits well: one port can serve a private camera network.

Windows: not officially supported as the server; passing a GPU or Coral through "may be difficult or impossible". We did not test it. Use Windows to open the web UI and run ssh:

Run in terminalpowershell
ssh -V

Mac: Apple Silicon is documented, with Docker Desktop or OrbStack. We did not test it.

Run in terminalbash
docker --version
docker compose version

Cameras: the docs recommend H.264 video, a separate low-resolution sub stream, and no Wi-Fi cameras. Create a view-only user in the camera's admin page.

Checklist:

  • [ ] Docker and Compose work
  • [ ] An x86_64 or arm64 machine
  • [ ] A camera with RTSP addresses for a small stream and, ideally, the full stream
  • [ ] A detector chosen (Step 4)
  • [ ] Ports 8971 and 8554 free
  • [ ] For the HTTPS section only: a domain with a DNS record, and ports 80 and 443 free

Tested by DIY Lab Hub: not yet. The commands come from the official starter files and docs read in October 2026; we did not run them.

Step 1: Create the folders on the Linux server#

Frigate keeps its config and database in config, and recordings and snapshots in storage. We use ~/docker_volumes/frigate, as all DIY Lab Hub guides do.

Linux#

Run in terminalbash
mkdir -p ~/docker_volumes/frigate/{config,storage,backups}
cd ~/docker_volumes/frigate
docker --version
docker compose version

Windows (PowerShell)#

Not supported as the server (see Before you start). Run this step on a Linux machine. To reach it from Windows:

Run in terminalpowershell
ssh <your-user>@<your-server-address>

Mac (Terminal)#

Same folders as Linux, if you run Frigate on the Mac:

Run in terminalbash
mkdir -p ~/docker_volumes/frigate/{config,storage,backups}
cd ~/docker_volumes/frigate
docker --version

Check it worked. ls ~/docker_volumes/frigate lists backups, config and storage.

Tip: On Linux install Docker Engine (not Docker Desktop) from the official Docker docs, as Frigate's getting-started guide says. The Snap build of Docker cannot use folders outside your home directory.

Step 2: Write the Compose file and the secrets file#

This is the official starter with four changes: the image is pinned, shm_size is set, the RTSP restream is published on the server only, and the camera password comes from a .env file. Frigate reads variables starting with FRIGATE_ when the config says {FRIGATE_NAME}.

Linux#

Run in terminalbash
cd ~/docker_volumes/frigate
printf 'FRIGATE_RTSP_PASSWORD=%s\n' '<camera-view-password>' > .env
chmod 600 .env
cat > docker-compose.yml << 'EOF'
services:
  frigate:
    container_name: frigate
    image: ghcr.io/blakeblackshear/frigate:0.18.2
    restart: unless-stopped
    stop_grace_period: 30s
    shm_size: "512mb"
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ./config:/config
      - ./storage:/media/frigate
      - type: tmpfs
        target: /tmp/cache
        tmpfs:
          size: 1000000000
    ports:
      - "8971:8971"
      - "127.0.0.1:8554:8554"
    environment:
      FRIGATE_RTSP_PASSWORD: "${FRIGATE_RTSP_PASSWORD}"
EOF
docker compose up -d
docker compose ps

Use a camera password of letters and digits: characters such as @ or / would need URL encoding in the camera address.

Windows (PowerShell)#

Not supported as the server. Put the same files on a Linux machine; see Step 1.

Mac (Terminal)#

The Mac uses the Arm image. Same folders, then:

Run in terminalbash
cd ~/docker_volumes/frigate
printf 'FRIGATE_RTSP_PASSWORD=%s\n' '<camera-view-password>' > .env
chmod 600 .env
cat > docker-compose.yml << 'EOF'
services:
  frigate:
    container_name: frigate
    image: ghcr.io/blakeblackshear/frigate:0.18.2-standard-arm64
    restart: unless-stopped
    stop_grace_period: 30s
    shm_size: "512mb"
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ./config:/config
      - ./storage:/media/frigate
    ports:
      - "8971:8971"
      - "127.0.0.1:8554:8554"
    environment:
      FRIGATE_RTSP_PASSWORD: "${FRIGATE_RTSP_PASSWORD}"
EOF
docker compose up -d
docker compose ps

The docs' Mac example leaves out the /tmp/cache memory mount, so this file does too. If you ever expose port 5000 on a Mac, map it to another host port such as 5001: macOS uses 5000 for AirPlay Receiver.

Check it worked. docker compose ps shows frigate running. The docs show no expected log text; read docker logs frigate --tail 100 for errors.

Tip: Compose reads .env from the folder you run it in. If the password looks empty, run docker compose config and check the FRIGATE_RTSP_PASSWORD line.

Step 3: Log in and replace the admin password#

On first start Frigate creates an admin user and prints the password in the log. The UI is on port 8971 with a self-signed certificate, so your browser will warn once.

Linux#

Run in terminalbash
cd ~/docker_volumes/frigate
docker logs frigate 2>&1 | head -n 120

Find the line that gives the admin user and its password. Then open https://<your-server-address>:8971, accept the certificate warning, and log in.

Windows (PowerShell)#

Read the log over SSH, then open the same address in your browser:

Run in terminalpowershell
ssh <your-user>@<your-server-address> "docker logs frigate 2>&1 | head -n 120"

Mac (Terminal)#

On the Mac that runs Frigate:

Run in terminalbash
docker logs frigate 2>&1 | head -n 120

Open https://localhost:8971.

In the UI, open Settings > Users and set a new admin password (at least 12 characters). Locked out? Set auth: reset_admin_password: true in config/config.yml; Frigate prints a new password at the next start.

Check it worked. You see the Frigate dashboard after login.

Tip: Save the new password in a password manager right away. Port 8971 has the login; do not use 5000 for daily use.

Step 4: Pick a detector and start it#

Frigate sends moving regions to a detector, which names the objects. Pick one type: the docs say detector types cannot be mixed. They also say a Coral is "no longer recommended for new Frigate installations".

Your hardwareDetector typeImage tagWhat to add
Intel 6th-gen or newer with graphics, Intel Arc, Intel NPUopenvino0.18.2pass /dev/dri/renderD128
NVIDIA GPU (driver 545 or newer, Maxwell or newer)onnx0.18.2-tensorrtNVIDIA Container Toolkit, GPU reservation, an ONNX model
Google Coral (USB or M.2)edgetpu0.18.2pass /dev/bus/usb
Apple Silicon MacApple Silicon detector client, run on the Mac0.18.2-standard-arm64extra_hosts line
Noneopenvino on CPU0.18.2nothing (testing only)

The docs' published inference times: about 15 ms for an Intel N100 or HD 630 with the default model, about 5 ms for an Arc A310, about 8 ms for an RTX 3050 with a tiny YOLOv9 model.

Linux#

Intel (OpenVINO). In docker-compose.yml, add this under the frigate: service:

File contentyaml
    devices:
      - /dev/dri/renderD128:/dev/dri/renderD128

Then put this in config/config.yml (these are the official getting-started settings, plus Intel video decoding):

File contentyaml
ffmpeg:
  hwaccel_args: preset-vaapi

detectors:
  ov:
    type: openvino
    device: GPU

model:
  width: 300
  height: 300
  input_tensor: nhwc
  input_pixel_format: bgr
  path: /openvino-model/ssdlite_mobilenet_v2.xml
  labelmap_path: /openvino-model/coco_91cl_bkgr.txt

NVIDIA. Install the NVIDIA driver and the NVIDIA Container Toolkit on the host. Change the image to ghcr.io/blakeblackshear/frigate:0.18.2-tensorrt and add:

File contentyaml
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]

The detector needs an ONNX model you export once. The detector docs page has a ready docker build command for YOLOv9; we do not copy it. Save the file as ~/docker_volumes/frigate/config/model_cache/yolo.onnx, then:

File contentyaml
ffmpeg:
  hwaccel_args: preset-nvidia

detectors:
  onnx:
    type: onnx

model:
  model_type: yolo-generic
  width: 320
  height: 320
  input_tensor: nchw
  input_dtype: float
  path: /config/model_cache/yolo.onnx
  labelmap_path: /labelmap/coco-80.txt

Coral (USB). Add the device to the service, and use this detector:

File contentyaml
    devices:
      - /dev/bus/usb:/dev/bus/usb
File contentyaml
detectors:
  coral:
    type: edgetpu
    device: usb

Apply any Compose change with docker compose up -d in ~/docker_volumes/frigate, and restart Frigate after editing config.yml:

Run in terminalbash
docker compose restart frigate

Windows (PowerShell)#

No detector steps: the server is Linux. Copy a config you edited on Windows to the server:

Run in terminalpowershell
scp .\config.yml <your-user>@<your-server-address>:~/docker_volumes/frigate/config/config.yml

Mac (Terminal)#

For the Apple NPU, set up and run the Apple Silicon detector client on the Mac first (we did not read or test its steps), and add this to the service:

File contentyaml
    extra_hosts:
      - "host.docker.internal:host-gateway"

Without the client, use the Intel config above with device: CPU and no devices: line. The docs list CPU mode for Arm64 hosts but call it "generally not recommended": fine for trying Frigate, not for daily use.

Check it worked. Open System > Metrics in the UI, which the docs point to for monitoring detection. Inference time should be near the numbers above, not hundreds of milliseconds. Run docker logs frigate --tail 100 and look for detector errors.

Tip: /dev/dri/renderD128 is the docs' example. Run ls /dev/dri on your host and use the renderD name you see.

Step 5: Add your first camera#

Version 0.18 has an Add Camera wizard in Settings > Global configuration > Camera management. Use it, or edit the config. The docs recommend a small stream for detection and the full one for recording.

Linux#

Merge this into config/config.yml, with your own camera addresses. {FRIGATE_RTSP_PASSWORD} is read from the environment:

File contentyaml
mqtt:
  enabled: False

cameras:
  front_door:
    ffmpeg:
      inputs:
        - path: rtsp://viewer:{FRIGATE_RTSP_PASSWORD}@<camera-address>:554/<sub-stream-path>
          roles:
            - detect
        - path: rtsp://viewer:{FRIGATE_RTSP_PASSWORD}@<camera-address>:554/<main-stream-path>
          roles:
            - record
    detect:
      width: 1280
      height: 720
    record:
      enabled: True

Set width and height to the real size of the detect stream. mqtt: enabled: False is fine until you connect Home Assistant. Frigate keeps video of tracked objects for 10 days by default.

Windows (PowerShell)#

Edit the file on the server over SSH, or copy it as in Step 4:

Run in terminalpowershell
ssh <your-user>@<your-server-address> "nano ~/docker_volumes/frigate/config/config.yml"

Mac (Terminal)#

Same file and settings as Linux. Edit ~/docker_volumes/frigate/config/config.yml, then:

Run in terminalbash
cd ~/docker_volumes/frigate
docker compose restart frigate

Check it worked. The camera tile shows live video on the dashboard, and walking in front of the camera creates an item under Review. The docker logs frigate output shows no repeating ffmpeg errors.

Tip: Keep the camera password in .env, so you can post config.yml in a forum with {FRIGATE_RTSP_PASSWORD} as is.

Step 6: Keep the cameras off the internet#

A camera that can call home is a risk. The docs suggest a server with two network ports so cameras sit on a private network "where they can be blocked from accessing the internet". This is done on your router, so it is the same everywhere.

Linux#

On your router or switch, not the server: put the cameras on their own VLAN or guest network, block them from the internet, let them talk only to the Frigate server, and forward no camera or Frigate port. Router brands differ, so there is no single command.

Windows (PowerShell)#

The same router steps. Nothing to run on Windows.

Mac (Terminal)#

The same router steps. Nothing to run on the Mac.

Check it worked. Frigate still shows live video after the block, and your router's log shows no camera traffic going to the internet.

Tip: Also turn off the camera's own cloud, UPnP and P2P features and change its default password. The router block is the safety net, not the only layer.

Put it behind HTTPS (with or without Traefik)#

Frigate serves HTTPS on 8971 with a self-signed certificate. For https://frigate.<your-domain> with a normal certificate, put a proxy in front: the docs say proxies should use port 8971 and that you can turn Frigate's own TLS off. Local-only users can skip this section. Both routes need a DNS record pointing to the server.

First, change config/config.yml:

File contentyaml
tls:
  enabled: False

auth:
  cookie_secure: True
  failed_login_rate_limit: "1/second;5/minute;20/hour"
  trusted_proxies:
    - <proxy-network-subnet>

The config reference advises cookie_secure with TLS. trusted_proxies makes the login limit count real client addresses, not your proxy; find the subnet with docker network inspect proxy. Then restart Frigate.

With Traefik#

On a server that already runs Traefik v3 with the Docker provider, add labels and remove the published 8971 port. This assumes an external Docker network called proxy and an entrypoint called https; use your own names. Create the network once:

Run in terminalbash
docker network create proxy

In docker-compose.yml, delete the "8971:8971" line, then add:

File contentyaml
    networks:
      - proxy
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=proxy"
      - "traefik.http.routers.frigate.rule=Host(`frigate.<your-domain>`)"
      - "traefik.http.routers.frigate.entrypoints=https"
      - "traefik.http.routers.frigate.tls=true"
      - "traefik.http.services.frigate.loadbalancer.server.port=8971"

and at the end of the file:

File contentyaml
networks:
  proxy:
    external: true

Start it with docker compose up -d.

Check it worked. curl -I https://frigate.<your-domain>/ returns an HTTP status line over HTTPS, and the login page loads with a valid certificate.

Without Traefik: Caddy#

Choose this if you have no Traefik. Caddy gets and renews its own certificates. Caddy's docs describe Let's Encrypt for public names and tls internal for a local certificate.

Run in terminalbash
docker network create proxy
mkdir -p ~/docker_volumes/caddy/{data,config}
cd ~/docker_volumes/caddy

Save this as ~/docker_volumes/caddy/docker-compose.yml. The image is caddy:2.11.7, the latest Caddy release read in October 2026:

File contentyaml
services:
  caddy:
    image: caddy:2.11.7
    container_name: caddy
    restart: unless-stopped
    ports:
      - "80:80/tcp"
      - "443:443/tcp"
      - "443:443/udp"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - ./data:/data
      - ./config:/config
    networks:
      - proxy

networks:
  proxy:
    external: true

Save this as ~/docker_volumes/caddy/Caddyfile for a public domain:

File contenttext
frigate.example.com {
    reverse_proxy frigate:8971
}

For a home-only name, use tls internal instead:

File contenttext
frigate.home.arpa {
    tls internal
    reverse_proxy frigate:8971
}

In the Frigate docker-compose.yml, delete the "8971:8971" line and add the proxy network exactly as in the Traefik example (without the labels). Start both stacks:

Run in terminalbash
cd ~/docker_volumes/caddy && docker compose up -d
cd ~/docker_volumes/frigate && docker compose up -d

For the home-only certificate, copy Caddy's root out and install it on each device. In a container Caddy does not install it for you:

Run in terminalbash
docker exec caddy find /data -name root.crt
docker cp caddy:<path-from-find> ./caddy-root.crt

Trust it on Windows in "Trusted Root Certification Authorities", on macOS in Keychain Access with "Always Trust", on Linux in your distribution's certificate store (general practice, not from the Frigate or Caddy docs). Run the docker commands on the server only.

Check it worked. curl -I https://frigate.example.com/ returns an HTTP status line. For a home-only name, the browser shows a padlock only after the root is trusted on that device.

Tip: Let's Encrypt needs the DNS record to point at the server and ports 80 and 443 to reach it. With tls: enabled: False, https://<server>:8971 stops working: that port now speaks plain HTTP. Use the proxy address.

Security and testing#

ControlHow
LoginUse port 8971. Port 5000 has no login and the docs say to limit it; our file does not publish it
RouterForward no camera or Frigate ports. Reach Frigate from outside only through your own VPN or the HTTPS proxy
CamerasOwn network, no internet, a view-only user, no cloud features
RTSP restream (8554)Unauthenticated by default; our file publishes it on the server only. A login can be set with go2rtc.rtsp.username and password
Secrets.env with chmod 600. The JWT secret is stored in config/.jwt_secret; back it up with the config
UpdatesThe 0.18.1 and 0.18.2 releases fixed security problems. Stay current

Quick tests on Linux after each change:

Run in terminalbash
cd ~/docker_volumes/frigate
docker compose ps
docker logs frigate --tail 100
curl -k -I https://localhost:8971/

On Windows use curl.exe -I https://frigate.<your-domain>/; on Mac, curl in Terminal.

What leaves the machine. Core use needs nothing: the CPU, Coral and OpenVINO detection models are bundled, and the UI has no outside fonts, scripts or analytics. These do call out (per the docs' network page):

  • Version check at startup to api.github.com. Switch it off with telemetry: version_check: False (the Home Assistant integration then cannot report new versions).
  • Model downloads once, when you turn on features such as semantic search, face recognition or licence plate reading (from HuggingFace or GitHub), cached in config/model_cache.
  • Frigate+, cloud AI (OpenAI, Google, Azure) and push notifications only when you set them up.
  • WebRTC in the web player may use Google's public STUN server.
  • MQTT goes to your broker, and leaves home only if the broker is in the cloud.

The docs' offline recipe: download models once, set telemetry: version_check: False, and set HF_HUB_OFFLINE: "1" and TRANSFORMERS_OFFLINE: "1" in the environment.

Common mistakes#

These come from the docs' own warnings, the issue tracker and discussions, and common AI assistant answers.

MistakeWhy it happensDo this instead
Leaving shm_size at Docker's 64 MBThe default is small. The FAQ lists "Fatal Python error: Bus error"; issue #6832 is one reportSet shm_size: "512mb" and check the docs' calculator. If it does not help, check process and file limits
Using port 5000, or forwarding itIt has no login. Issue #17883 asks for a way to turn it off in host mode and is openUse 8971, keep 5000 unpublished, forward neither on the router
Detecting on the full-resolution streamOne stream seems simpler. The docs say detection is the only stream Frigate decodesA small sub stream for detect (5 fps), the main stream for record
Hiding objects with a motion maskThe name suggests it. The docs warn masks only stop motion from starting detectionUse an object filter mask for a fixed false positive
localhost as the MQTT hostInside the container it is Frigate itself. The FAQ: "Unable to publish to MQTT: client is not connected"Use the broker machine's address
Database or /media on a network shareThe FAQ lists "Error: Database Is Locked" for SQLite on sharesKeep config on a local disk
Trusting the -tensorrt nameIssue #24397 (closed September 2026) reported the 0.18.0 image silently using a slower path (not retested by us)Compare inference time on the Metrics page with the docs' table
Buying a Coral for a new buildOlder guides say Coral. The hardware page now says "no longer recommended"Use Intel OpenVINO or NVIDIA unless power use matters most
AI assistants: old settings such as clean_copy, an rtmp: block, or masks as a plain 0,461,... stringChatbots copy old config files. 0.18 removed clean_copy and changed the mask formatCheck keys against the configuration reference or use the Settings UI
AI assistants: Compose with :latest, version:, port 5000 and two detector typesOld posts do this. The docs' tags are stable or a version number, the UI is on 8971, and types cannot be mixedUse 0.18.2, no version: line, 8971, one detector type

Tip: Back up config/ (it holds config.yml and frigate.db) before every upgrade. The docs say so, and 0.18 rewrites some settings on first start.

Tip: Switch on Motion boxes in the camera's debug view and watch for a day. Trees and timestamps that keep triggering motion are what masks are for.

Tip: Change one thing at a time and run docker logs frigate --tail 100 after each change.

Troubleshooting#

ProblemSolution
"Fatal Python error: Bus error"shm_size too small. Raise it and run docker compose up -d
RuntimeError: can't start new threadThe PID limit, often followed by a Bus error. Compare cat /sys/fs/cgroup/pids.current with pids.max in the container, then set pids_limit in Compose
OSError: [Errno 24] Too many open filesAdd ulimits: nofile: soft: 65535, hard: 65535 under the service
No video from a cameraTest the address in a player on another machine. Frigate uses TCP for RTSP, so a stream that works in VLC may still fail
Green or garbled picturedetect.width and detect.height do not match the stream
Very high CPUNo detector set, or detect uses the main stream
Detector not foundCheck the devices: lines and the log. For a USB Coral see the docs' EdgeTPU page
Cannot play recordingsThe camera sends H.265. Switch to H.264 or transcode
Locked outSet auth: reset_admin_password: true, restart, read the new password in the log, then set it back to false
Config error after upgradeFrigate saves backup_config.yaml when it migrates. Compare, or restore your backup and the old tag

Known reports (October 2026)#

  • Discussion #24695: a 401 after the Home Assistant Android app is suspended, on 0.18.2 (unanswered when read).
  • Discussion #24805: the motion MQTT topic not firing on some cameras, on 0.18.2 (unanswered).
  • Discussion #24811: the Docker overlay filling up, on 0.18.2 (unanswered).
  • Issue #17883: no way to turn off the unauthenticated port in host mode (open).

Diagnostics: docker compose ps, docker logs frigate --tail 100, docker inspect frigate, docker stats frigate.

Updates and backups#

Update. Read the release notes, back up config, change the tag, and pull. The stable tag moves when you pull, so we pin.

Run in terminalbash
cd ~/docker_volumes/frigate
docker compose down
# edit docker-compose.yml: change the tag, then:
docker compose pull
docker compose up -d
docker logs frigate --tail 100

Back up. Recordings are large; settings and database are small and precious. This script skips the model cache:

Run in terminalbash
cd ~/docker_volumes/frigate
cat > backup.sh << 'EOF'
#!/bin/bash
set -e
cd ~/docker_volumes/frigate
docker compose down
mkdir -p backups
tar -czf "backups/frigate-config-$(date +%F).tar.gz" --exclude=config/model_cache config .env docker-compose.yml
chmod 600 backups/frigate-config-*.tar.gz
docker compose up -d
EOF
chmod 700 backup.sh

Schedule it at 03:00 with crontab -e on Linux or Mac:

File contenttext
0 3 * * * $HOME/docker_volumes/frigate/backup.sh

The archive holds your camera password: keep it private and copy it to another machine.

Restore test. Unpack one archive into a new empty folder, never over the live one:

Run in terminalbash
mkdir -p /tmp/restore-test && tar -xzf backups/frigate-config-<date>.tar.gz -C /tmp/restore-test
ls /tmp/restore-test/config

Roll back. Stop Frigate, restore your backed-up config, set the older tag (such as 0.18.1) in Compose, and run docker compose up -d.

Windows (PowerShell)#

Not for the server. Copy the archive off the Linux server:

Run in terminalpowershell
scp <your-user>@<your-server-address>:~/docker_volumes/frigate/backups/frigate-config-<date>.tar.gz .

Mac (Terminal)#

The same scp command works from Terminal.

Performance and resources#

The docs give no overall RAM or CPU number, so we give none. Their knobs:

  • shm: about 210 MB for 2 cameras at 720p, plus up to 50 MB for logs. More or bigger cameras need more.
  • Detect settings: 5 fps is "correct for almost all cameras"; raising it costs CPU and GPU for little gain.
  • Model size: 320x320 is the best choice for most setups.
  • Decoding: hardware decoding (preset-vaapi, preset-nvidia) cuts CPU use.
  • Detectors: with many cameras, add a second detector of the same type.
  • Port 8971: the 0.18 release notes say it is faster than 5000 for live and history views with several cameras.

Monitor with docker stats frigate and the UI's System page.

FAQ#

Is Frigate free? Yes. The code is MIT licensed. The name and logo are trademarks of Frigate, Inc. Frigate+ (training your own models) is an optional paid service.

Do I need Home Assistant or MQTT? No. MQTT is optional and required only for the Home Assistant integration.

Do I need a Coral or a GPU? You need some detector. The docs say CPU detection is for testing only.

Can I run Frigate on Windows? Not officially. Use a Linux machine and open the web UI from Windows.

Does Frigate send my video to the cloud? Not by default. Only the optional features listed under "What leaves the machine" do.

Sources#

Checked against the official docs on 2026-10-30.