219 lines
5.8 KiB
Nix
219 lines
5.8 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
let
|
|
version = "0.15.1";
|
|
configVersion = "0.15-1";
|
|
containerDataPath = "/var/lib/frigate";
|
|
mediaPath = config.homefree.services.frigate.media-path or "${containerDataPath}/media";
|
|
cameras-filtered = lib.filter (camera: camera.enable == true) config.homefree.services.frigate.cameras;
|
|
|
|
frigate-config = {
|
|
version = configVersion;
|
|
|
|
detectors = {
|
|
coral = {
|
|
type = "edgetpu";
|
|
device = "usb";
|
|
# num_threads = 3;
|
|
};
|
|
};
|
|
|
|
ffmpeg = {
|
|
## Intel
|
|
hwaccel_args = "preset-intel-qsv-h264";
|
|
|
|
## Raspberry Pi
|
|
# hwaccel_args = "-c:v h264_v4l2m2m";
|
|
};
|
|
|
|
mqtt = {
|
|
host = "10.0.0.1";
|
|
port = 1883;
|
|
topic_prefix = "frigate";
|
|
## Must be unique if running multiple instances
|
|
client_id = "frigate";
|
|
stats_interval = 60;
|
|
};
|
|
|
|
objects = {
|
|
track = [
|
|
"person"
|
|
"bicycle"
|
|
"dog"
|
|
"cat"
|
|
];
|
|
};
|
|
|
|
record = {
|
|
enabled = true;
|
|
# ## Minutes
|
|
# expire_interval = 60;
|
|
retain = {
|
|
days = 3;
|
|
mode = "all";
|
|
};
|
|
alerts = {
|
|
retain = {
|
|
days = 30;
|
|
mode = "motion";
|
|
};
|
|
};
|
|
detections = {
|
|
retain = {
|
|
days = 30;
|
|
mode = "motion";
|
|
};
|
|
};
|
|
};
|
|
|
|
snapshots = {
|
|
# Optional: Enable writing jpg snapshot to /media/frigate/clips (default: shown below)
|
|
# This value can be set via MQTT and will be updated in startup based on retained value
|
|
enabled = true;
|
|
# Optional: print a timestamp on the snapshots (default: shown below)
|
|
timestamp = false;
|
|
# Optional: draw bounding box on the snapshots (default: shown below)
|
|
bounding_box = false;
|
|
# Optional: crop the snapshot (default: shown below)
|
|
crop = false;
|
|
# # Optional: height to resize the snapshot to (default: original size)
|
|
# height = 175;
|
|
# Optional: Camera override for retention settings (default: global values)
|
|
retain = {
|
|
# Required: Default retention days (default: shown below)
|
|
default = 10;
|
|
# Optional: Per object retention days
|
|
objects = {
|
|
person = 15;
|
|
};
|
|
};
|
|
};
|
|
|
|
birdseye = {
|
|
enabled = true;
|
|
mode = "continuous";
|
|
};
|
|
|
|
cameras = lib.listToAttrs (lib.map (camera: {
|
|
name = camera.name;
|
|
value = {
|
|
enabled = camera.enable;
|
|
ffmpeg = {
|
|
inputs = [
|
|
{
|
|
path = camera.path;
|
|
roles = [
|
|
"audio"
|
|
"detect"
|
|
"record"
|
|
];
|
|
}
|
|
];
|
|
};
|
|
detect = {
|
|
width = camera.width;
|
|
height = camera.height;
|
|
fps = 5;
|
|
};
|
|
};
|
|
}) cameras-filtered);
|
|
};
|
|
|
|
config-yaml = (pkgs.formats.yaml {}).generate "frigate-config.yaml" frigate-config;
|
|
|
|
preStart = ''
|
|
mkdir -p ${containerDataPath}/config
|
|
mkdir -p ${mediaPath}
|
|
|
|
cp ${config-yaml} ${containerDataPath}/config/config.yaml
|
|
'';
|
|
in
|
|
{
|
|
environment.systemPackages= [
|
|
## Google Coral (Edge TPU) USB Support
|
|
pkgs.libedgetpu
|
|
];
|
|
|
|
virtualisation.oci-containers.containers = if config.homefree.services.frigate.enable == true then {
|
|
frigate = {
|
|
image = "ghcr.io/blakeblackshear/frigate:${version}";
|
|
|
|
autoStart = true;
|
|
|
|
extraOptions = [
|
|
# "--pull=always"
|
|
## 1GB of memory, reduces SSD/SD Card wear
|
|
"--mount=type=tmpfs,target=/tmp/cache,tmpfs-size=1000000000"
|
|
"--shm-size=512M"
|
|
# "--network=bridge"
|
|
"--device=/dev/bus/usb:/dev/bus/usb" # Passes the USB Coral, needs to be modified for other versions
|
|
"--device=/dev/dri/card1:/dev/dri/card1" # For intel hwaccel, needs to be updated for your hardware
|
|
"--device=/dev/dri/renderD128:/dev/dri/renderD128" # For intel hwaccel, needs to be updated for your hardware
|
|
"--cap-add=CAP_PERFMON" # For GPU statistics
|
|
"--privileged"
|
|
];
|
|
|
|
ports = [
|
|
"0.0.0.0:8971:8971"
|
|
"8554:8554" # RTSP feeds
|
|
"8555:8555/tcp" # WebRTC over tcp
|
|
"8555:8555/udp" # WebRTC over udp
|
|
];
|
|
|
|
volumes = [
|
|
"/etc/localtime:/etc/localtime:ro"
|
|
"${containerDataPath}/config:/config"
|
|
## @TODO: make this configurable
|
|
"${mediaPath}:/media/frigate"
|
|
];
|
|
|
|
environment = {
|
|
TZ = config.homefree.system.timeZone;
|
|
};
|
|
};
|
|
} else {};
|
|
|
|
systemd.services.podman-frigate = {
|
|
after = [ "dns-ready.service" ];
|
|
requires = [ "dns-ready.service" ];
|
|
partOf = [ "nftables.service" ];
|
|
serviceConfig = {
|
|
ExecStartPre = [ "!${pkgs.writeShellScript "frigate-prestart" preStart}" ];
|
|
};
|
|
};
|
|
|
|
# systemd.services.podman-create-frigate-network = {
|
|
# serviceConfig.Type = "oneshot";
|
|
# wantedBy = [ "podman-frigate.service" ];
|
|
# script = ''
|
|
# podman network create -d ipvlan --subnet 10.0.0.0/24 --ip-range 10.0.99.0/24 --ipam-driver host-local podnet
|
|
# '';
|
|
# };
|
|
|
|
homefree.service-config = if config.homefree.services.frigate.enable == true then [
|
|
{
|
|
label = "frigate";
|
|
name = "NVR (Network Video Recorer)";
|
|
project-name = "Frigate";
|
|
systemd-service-names = [
|
|
"podman-frigate"
|
|
];
|
|
reverse-proxy = {
|
|
enable = true;
|
|
subdomains = [ "nvr" "frigate" ];
|
|
http-domains = [ "homefree.lan" config.homefree.system.localDomain ];
|
|
https-domains = [ config.homefree.system.domain ];
|
|
host = "10.0.0.1";
|
|
port = 8971;
|
|
ssl = true;
|
|
ssl-no-verify = true;
|
|
public = config.homefree.services.frigate.public;
|
|
};
|
|
backup = if config.homefree.services.frigate.enable-backup-media then {
|
|
paths = [
|
|
mediaPath
|
|
];
|
|
} else {};
|
|
}
|
|
] else [];
|
|
}
|
|
|