From 7dc9a762a00cec673d0b6e5c5673ba706191c973 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 1 Jul 2026 19:49:26 +0000 Subject: [PATCH] frigate.sh: interactive camera wizard generates go2rtc + cameras config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously Frigate always wrote a placeholder config.yml the operator had to hand-edit to add cameras. Now install_frigate prompts to add cameras one at a time (name, RTSP IP/port/user/password/path, optional sub-stream, enabled, notifications), matching the go2rtc + cameras structure used in production frigate configs: - Each camera gets a go2rtc stream entry (+ optional _sub for detection) and a cameras: block with ffmpeg inputs/roles, detect, notifications - RTSP credentials/IPs are written to .env as FRIGATE_* variables (first camera gets FRIGATE_RTSP_USER/PASSWORD, later cameras get numbered suffixes _1, _2, ... to avoid collisions) and referenced in config.yml via Frigate's {FRIGATE_VAR} substitution syntax — secrets never appear in the YAML directly - docker-compose.yml now includes env_file: .env so those vars actually reach the container for substitution to work - Skipping all camera prompts falls back to the original starter config.yml for manual editing, preserving existing behavior - README and DRY-RUN summary updated to reflect the new flow Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01LQJBvqzXeyuhhAcAA3Q5Wq --- services/frigate.sh | 185 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 172 insertions(+), 13 deletions(-) diff --git a/services/frigate.sh b/services/frigate.sh index 90249f0..37737a4 100644 --- a/services/frigate.sh +++ b/services/frigate.sh @@ -9,7 +9,10 @@ # Ported from ubuntu-post-install-24.04-crowdsec.sh (# ---- FRIGATE NVR ----). # Own ~/docker/frigate/ with a standalone docker-compose.yml + .env + config.yml. # Auto-enables /dev/dri/renderD128 for hardware detection (Intel/AMD) when present. -# YOU MUST edit config/config.yml to add your camera RTSP streams before starting. +# Interactively prompts for cameras — RTSP user/pass/IP go in .env as +# FRIGATE_* vars, which config.yml references via Frigate's {FRIGATE_VAR} +# substitution syntax so credentials never appear in the YAML directly. +# Skip the camera prompts to get a starter config.yml to edit by hand. # ── Standalone bootstrap ────────────────────────────────────────────────────── # Detected when the script is executed directly rather than sourced by setup.sh. @@ -205,7 +208,8 @@ install_frigate() { echo " - Create $FRIGATE_DIR with docker-compose.yml + .env + config/config.yml" echo " - Auto-enable /dev/dri/renderD128 for GPU-assisted detection if present" echo " - Expose ports 5000 (web), 8554 (RTSP restream), 8555 (WebRTC)" - echo " - Write a starter config.yml — edit to add camera streams before starting" + echo " - Prompt to add cameras interactively (RTSP creds go in .env)" + echo " or write a starter config.yml if none are added" echo " - Offer a Caddy reverse proxy and to start the container" return 0 fi @@ -258,6 +262,8 @@ services: restart: unless-stopped privileged: true shm_size: "256mb" + env_file: + - .env environment: - TZ=$TZ_VAL $DEVICE_BLOCK @@ -276,15 +282,117 @@ $DEVICE_BLOCK ${_CADDY_NET_BLOCK}${_CADDY_NET_SECTION} FRIGATE_COMPOSE - cat > .env << FRIGATE_ENV -FRIGATE_MEDIA=$FRIGATE_MEDIA -CADDY_NET=$SITE_CADDY_NET -FRIGATE_ENV - mkdir -p config mkdir -p "$FRIGATE_MEDIA" - cat > config/config.yml << 'FRIGATE_CONFIG' + # ── Camera wizard ──────────────────────────────────────────────────────── + # Credentials/IPs go in .env as FRIGATE_* variables; Frigate substitutes + # any {FRIGATE_VAR} placeholder in config.yml from its container env at + # startup, so RTSP secrets never need to be typed into the YAML directly. + local GO2RTC_BLOCK="" CAMERAS_BLOCK="" ENV_CAM_VARS="" CAM_INDEX=0 + while true; do + local ADD_CAM="" + if [ "$CAM_INDEX" -eq 0 ]; then + prompt_yn "Add a camera now? (y/n):" "y" ADD_CAM + else + prompt_yn "Add another camera? (y/n):" "n" ADD_CAM + fi + [[ "$ADD_CAM" =~ ^[Yy]$ ]] || break + + local CAM_NAME="" + prompt_text " Camera name (e.g. front_door):" "camera$((CAM_INDEX+1))" CAM_NAME + CAM_NAME="$(echo "$CAM_NAME" | tr '[:upper:] ' '[:lower:]_' | tr -cd 'a-z0-9_')" + CAM_NAME="${CAM_NAME:-camera$((CAM_INDEX+1))}" + local CAM_UPPER="${CAM_NAME^^}" + + local CAM_IP="" + prompt_text " ${CAM_NAME} RTSP IP address:" "" CAM_IP + local CAM_PORT="" + prompt_text " ${CAM_NAME} RTSP port [554]:" "554" CAM_PORT + local CAM_USER="" + prompt_text " ${CAM_NAME} RTSP username:" "admin" CAM_USER + local CAM_PASS="" + prompt_text " ${CAM_NAME} RTSP password (blank = generate one):" "" CAM_PASS + [ -z "$CAM_PASS" ] && CAM_PASS="$(generate_password 20)" + + local CAM_PATH="" + prompt_text " ${CAM_NAME} RTSP path (use {sub} for main/sub-stream marker) [/cam/realmonitor?channel=1&subtype={sub}#backchannel=0]:" \ + "/cam/realmonitor?channel=1&subtype={sub}#backchannel=0" CAM_PATH + + local CAM_SUBSTREAM="" + prompt_yn " Add a lower-res sub-stream for detection? (y/n):" "y" CAM_SUBSTREAM + + local CAM_ENABLED="" + prompt_yn " Enable ${CAM_NAME} immediately? (y/n):" "y" CAM_ENABLED + local CAM_NOTIFY="" + prompt_yn " Enable notifications for ${CAM_NAME}? (y/n):" "n" CAM_NOTIFY + + # First camera's credentials get no suffix (FRIGATE_RTSP_USER); each + # camera after that gets an index suffix (…USER1, …USER2, …) so + # cameras with different logins don't collide. + local IDX_SUFFIX="" + [ "$CAM_INDEX" -gt 0 ] && IDX_SUFFIX="$CAM_INDEX" + local VAR_USER="FRIGATE_RTSP_USER${IDX_SUFFIX}" + local VAR_PASS="FRIGATE_RTSP_PASSWORD${IDX_SUFFIX}" + local VAR_IP="FRIGATE_${CAM_UPPER}_IP" + + ENV_CAM_VARS="${ENV_CAM_VARS}${VAR_USER}=${CAM_USER} +${VAR_PASS}=${CAM_PASS} +${VAR_IP}=${CAM_IP} +" + + local MAIN_PATH="${CAM_PATH//\{sub\}/0}" + local SUB_PATH="${CAM_PATH//\{sub\}/1}" + + GO2RTC_BLOCK="${GO2RTC_BLOCK} ${CAM_NAME}: + - rtsp://{${VAR_USER}}:{${VAR_PASS}}@{${VAR_IP}}:${CAM_PORT}${MAIN_PATH} +" + local INPUTS_BLOCK + if [[ "$CAM_SUBSTREAM" =~ ^[Yy]$ ]]; then + GO2RTC_BLOCK="${GO2RTC_BLOCK} ${CAM_NAME}_sub: + - rtsp://{${VAR_USER}}:{${VAR_PASS}}@{${VAR_IP}}:${CAM_PORT}${SUB_PATH} +" + INPUTS_BLOCK=" - path: rtsp://127.0.0.1:8554/${CAM_NAME} + input_args: preset-rtsp-restream + roles: + - record + - path: rtsp://127.0.0.1:8554/${CAM_NAME}_sub + input_args: preset-rtsp-restream + roles: + - detect" + else + INPUTS_BLOCK=" - path: rtsp://127.0.0.1:8554/${CAM_NAME} + input_args: preset-rtsp-restream + roles: + - detect + - record" + fi + GO2RTC_BLOCK="${GO2RTC_BLOCK} +" + + local ENABLED_VAL="false"; [[ "$CAM_ENABLED" =~ ^[Yy]$ ]] && ENABLED_VAL="true" + local NOTIFY_VAL="false"; [[ "$CAM_NOTIFY" =~ ^[Yy]$ ]] && NOTIFY_VAL="true" + + CAMERAS_BLOCK="${CAMERAS_BLOCK} ${CAM_NAME}: + enabled: ${ENABLED_VAL} + ffmpeg: + inputs: +${INPUTS_BLOCK} + detect: + enabled: true + width: 640 + height: 480 + fps: 5 + notifications: + enabled: ${NOTIFY_VAL} + +" + CAM_INDEX=$((CAM_INDEX+1)) + done + + if [ "$CAM_INDEX" -eq 0 ]; then + # No cameras entered — write a starter config the operator edits by hand. + cat > config/config.yml << 'FRIGATE_CONFIG' # Frigate Configuration — Docs: https://docs.frigate.video # # ⚠️ YOU MUST EDIT THIS FILE to add your cameras before starting Frigate. @@ -319,6 +427,44 @@ snapshots: retain: default: 7 FRIGATE_CONFIG + else + cat > config/config.yml << FRIGATE_CONFIG +# Frigate Configuration — Docs: https://docs.frigate.video +# +# RTSP credentials/IPs come from .env — Frigate substitutes {FRIGATE_VAR} +# placeholders below from the container's environment at startup. + +mqtt: + enabled: false # Set to true and configure if you use Home Assistant + +go2rtc: + streams: +${GO2RTC_BLOCK} +cameras: +${CAMERAS_BLOCK} +detectors: + default: + type: cpu # Change to 'edgetpu' for Coral TPU or 'openvino' for Intel GPU + +record: + enabled: true + retain: + days: 7 + mode: motion + +snapshots: + enabled: true + retain: + default: 7 +FRIGATE_CONFIG + fi + + cat > .env << FRIGATE_ENV +FRIGATE_MEDIA=$FRIGATE_MEDIA +CADDY_NET=$SITE_CADDY_NET +${ENV_CAM_VARS} +FRIGATE_ENV + chmod 600 .env chown -R "$ACTUAL_USER:$ACTUAL_USER" "$FRIGATE_DIR" chown -R "$ACTUAL_USER:$ACTUAL_USER" "$FRIGATE_MEDIA" 2>/dev/null || true @@ -336,7 +482,8 @@ security cameras. Detects people, cars, animals, and more. - RTSP restream: port 8554 - WebRTC: port 8555 - Recordings: \`$FRIGATE_MEDIA\` -- Config: \`config/config.yml\` — **add your camera RTSP streams here** +- Config: \`config/config.yml\` — cameras configured during install ($CAM_INDEX added) +- Credentials: \`.env\` — RTSP user/pass/IP per camera as FRIGATE_* variables ## Manage \`\`\`bash @@ -347,8 +494,14 @@ docker compose logs -f # logs docker compose pull && docker compose up -d # update \`\`\` +## Adding/editing cameras later +Re-run the installer (\`sudo ./setup.sh frigate\`) to add more cameras through +the same wizard, or edit \`config/config.yml\` and \`.env\` by hand — camera +credentials in config.yml use Frigate's \`{FRIGATE_VAR}\` substitution syntax, +resolved from \`.env\` at container startup. + ## First steps -1. Edit \`config/config.yml\` — add your camera RTSP URLs under \`cameras:\` +1. Review \`config/config.yml\` — adjust detection zones, masks, retention 2. Start Frigate: \`docker compose up -d\` 3. Open http://localhost:5000 to view cameras and configure detection zones @@ -359,17 +512,23 @@ docker compose pull && docker compose up -d # update MD echo "" - log_warning "Edit config/config.yml to add your camera RTSP streams before starting." + local START_DEFAULT="n" + if [ "$CAM_INDEX" -eq 0 ]; then + log_warning "No cameras added — edit config/config.yml to add camera RTSP streams before starting." + else + log_success "$CAM_INDEX camera(s) configured." + START_DEFAULT="y" + fi echo "" local START_FRIGATE="" - prompt_yn "Start Frigate now anyway? (y/n):" "n" START_FRIGATE + prompt_yn "Start Frigate now? (y/n):" "$START_DEFAULT" START_FRIGATE if [ "$START_FRIGATE" = "y" ] || [ "$START_FRIGATE" = "Y" ]; then docker compose up -d && log_success "Frigate started" || log_warning "Failed to start — check: docker compose logs" fi echo "" echo " Access at: http://localhost:5000" - echo " Config: $FRIGATE_DIR/config/config.yml (add cameras here)" + echo " Config: $FRIGATE_DIR/config/config.yml" echo "" }