{ lib, config, inputs, pkgs, ... }: let securePort = builtins.toString (lib.custom.autoport "frigate-secure"); volumePath = "/overseer/services"; sopsFolder = inputs.nix-secrets + "/sops"; frigateConfig = pkgs.writeText "frigate-config.yaml" ( lib.generators.toYAML { } { auth.enabled = false; # Proxy auth tls.enabled = false; # off because we're doing ssl through the proxy proxy = { logout_url = "https://frigate.wanderingcrow.net/caddy-security/oauth2/generic/logout"; default_role = "viewer"; header_map = { user = "Remote-User"; role = "Remote-Role"; }; }; mqtt = { enabled = true; host = "host.containers.internal"; port = 1883; }; ui = { timezone = "America/New_York"; time_format = "24hour"; }; ################### # go2rtc restream # ################### go2rtc = { streams = { wce-0001 = [ "rtsp://thingino:thingino@192.168.150.1:554/ch0" ]; wce-0001_sub = [ "rtsp://thingino:thingino@192.168.150.1:554/ch1" ]; wce-0002 = [ "rtsp://thingino:thingino@192.168.150.2:554/ch0" ]; wce-0002_sub = [ "rtsp://thingino:thingino@192.168.150.2:554/ch1" ]; }; }; ############# # Detectors # ############# detectors = { coral = { type = "edgetpu"; device = "usb"; }; }; objects = { track = [ "person" "cat" "dog" ]; }; review = { alerts = { labels = [ "person" "cat" ]; }; }; #################### # Data Persistence # #################### record = { enabled = true; retain.days = 0; # as per official documentation alerts.retain.days = 14; detections.retain.days = 14; }; ################# # Camera config # ################# cameras = { wce-0001 = { ffmpeg = { inputs = [ { path = "rtsp://127.0.0.1:8554/wce-0001"; roles = [ "record" ]; } { path = "rtsp://127.0.0.1:8554/wce-0001_sub"; roles = [ "detect" ]; } ]; }; motion = { enabled = true; mask = [ "0,0,0.196,0.002,0.195,0.045,0,0.043" # timestamp "0.898,0,0.896,0.045,1,0.048,0.999,0.002" # uptime ]; }; detect.enabled = true; record.continuous.days = 7; review = { alerts.labels = [ ]; detections.labels = [ "person" "cat" ]; }; }; wce-0002 = { ffmpeg = { inputs = [ { path = "rtsp://127.0.0.1:8554/wce-0002"; roles = [ "record" ]; } { path = "rtsp://127.0.0.1:8554/wce-0002_sub"; roles = [ "detect" ]; } ]; }; motion = { enabled = true; mask = [ "0,0,0.196,0.002,0.195,0.045,0,0.043" # timestamp "0.898,0,0.896,0.045,1,0.048,0.999,0.002" # uptime ]; }; detect.enabled = true; }; }; } ); in { sops = { templates."frigate_env".content = '' FRIGATE_JWT_SECRET=${config.sops.placeholder."frigate/jwt"} ''; secrets = { "frigate/jwt" = { sopsFile = "${sopsFolder}/services.yaml"; }; }; }; systemd.tmpfiles.rules = [ "d ${volumePath}/frigate" "d ${volumePath}/frigate/media/frigate" "d ${volumePath}/frigate/db" "f ${volumePath}/frigate/db/frigate.db" ]; virtualisation.quadlet = { containers = { frigate.containerConfig = { image = "ghcr.io/blakeblackshear/frigate:0.17.0-beta1"; environmentFiles = [ config.sops.templates."frigate_env".path ]; devices = [ "/dev/bus/usb:/dev/bus/usb" ]; shmSize = "612m"; volumes = [ "/etc/localtime:/etc/localtime:ro" "${volumePath}/frigate/media/frigate:/media/frigate" "${frigateConfig}:/config/config.yaml:ro" # :ro to set to readonly "${volumePath}/frigate/db/frigate.db:/config/frigate.db" ]; publishPorts = [ "${securePort}:8971" ]; }; }; }; services.caddy = { enable = true; virtualHosts."frigate.wanderingcrow.net".extraConfig = '' @auth { path /caddy-security/* } route @auth { authenticate with myportal } route /* { authorize with frigate reverse_proxy http://localhost:${securePort} } ''; }; }