From 92c96dc678b7755095e23f955822e67a07e6fa87 Mon Sep 17 00:00:00 2001 From: jgitta Date: Wed, 8 Jul 2026 14:13:20 -0500 Subject: [PATCH] fix: restore files unintentionally reverted by sync commit - restore jgpc/ layout (undo accidental revert to thinkstation/), homelab-overview.md (June 13 version), docs/jarvis doc, owncloud scripts, siklos/beszel compose - re-remove jellyfin/node-exporter and siklos/monitoring (replaced by Beszel) - jgpc/frigate/docker-compose.yml: update to newer local version (cpuset pinning, 8G limit) - root frigate-* files are local working copies -> gitignored --- .gitignore | 3 + docs/jarvis-build-documentation.docx | Bin 0 -> 19977 bytes homelab-overview.md | 27 ++- jellyfin/node-exporter/docker-compose.yml | 15 -- frigate-config.yml => jgpc/frigate/config.yml | 0 .../frigate/docker-compose.yml | 0 .../frigate/frigate-cameras.md | 0 jgpc/frigate/frigate-cctv-setup.md | 176 ++++++++++++++++++ .../open-webui/docker-compose.yml | 0 .../stirling-pdf/docker-compose.yml | 0 owncloud/README.md | 76 ++++++++ owncloud/organize_photos.sh | 72 +++++++ siklos/beszel/docker-compose.yml | 27 +++ siklos/monitoring/docker-compose.yml | 65 ------- thinkstation/frigate/docker-compose.yml | 35 ---- 15 files changed, 375 insertions(+), 121 deletions(-) create mode 100644 docs/jarvis-build-documentation.docx delete mode 100644 jellyfin/node-exporter/docker-compose.yml rename frigate-config.yml => jgpc/frigate/config.yml (100%) rename frigate-docker-compose.yml => jgpc/frigate/docker-compose.yml (100%) rename frigate-cameras.md => jgpc/frigate/frigate-cameras.md (100%) create mode 100644 jgpc/frigate/frigate-cctv-setup.md rename {thinkstation => jgpc}/open-webui/docker-compose.yml (100%) rename {thinkstation => jgpc}/stirling-pdf/docker-compose.yml (100%) create mode 100644 owncloud/README.md create mode 100755 owncloud/organize_photos.sh create mode 100644 siklos/beszel/docker-compose.yml delete mode 100644 siklos/monitoring/docker-compose.yml delete mode 100644 thinkstation/frigate/docker-compose.yml diff --git a/.gitignore b/.gitignore index 7390421..d126e0e 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,6 @@ kopia-docker-compose-fixed.yml ocis-credentials.md *.bak *.bak2 +frigate-cameras.md +frigate-config.yml +frigate-docker-compose.yml diff --git a/docs/jarvis-build-documentation.docx b/docs/jarvis-build-documentation.docx new file mode 100644 index 0000000000000000000000000000000000000000..acbcdf75c5dffc694390e23eb6411637dcde3b4b GIT binary patch literal 19977 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 c2i;Iyf?^8PDXidvNQyy/` on each host using **absolute paths**. @@ -120,7 +120,7 @@ All stack data volumes are stored at `/srv/docker//` on each host us |---|---|---|---|---| | Portainer | portainer/portainer-ce:latest | 9000, 9443 | portainer.jgitta.com | Docker management UI | | Pi-hole | pihole/pihole:latest | 53 (DNS), 8080 | pihole.jgitta.com | DNS ad blocker | -| Open WebUI | ghcr.io/open-webui/open-webui:main | 3000 | ai.jgitta.com | AI chat UI (connects to Ollama on ThinkStation) | +| Open WebUI | ghcr.io/open-webui/open-webui:main | 3000 | ai.jgitta.com | AI chat UI (connects to Ollama on jgpc) | | LiteLLM | litellm:latest | 4000 | — | Centralized LLM API gateway | | OnlyOffice | onlyoffice/documentserver | 8880 | office.jgitta.com | Online document editing (used by Nextcloud) | | Homarr | homarr:latest | 7575 | homarr.jgitta.com | Dashboard | @@ -164,7 +164,7 @@ Media storage is mounted at `/mnt/media` on the jellyfin host and presented as ` --- -### thinkstation-p710 — 192.168.88.41 — AI / Workstation Host +### jgpc — 192.168.88.41 — AI / Workstation Host | Service | Image | Port | Purpose | |---|---|---|---| @@ -174,6 +174,20 @@ Media storage is mounted at `/mnt/media` on the jellyfin host and presented as ` | Stirling PDF | frooodle/s-pdf:latest | 8081 | PDF tools web UI | | Portainer Agent | portainer/agent:latest | 9001 | Managed by siklos Portainer | +#### Printing (jgpc) + +The jgpc is the print server for the HP PageWide Color Flow MFP 586. + +| Item | Value | +|---|---| +| Printer | HP PageWide Color Flow MFP 586 | +| IP | 192.168.88.89 (static DHCP reservation, MAC: `ec:8e:b5:c0:d0:48`) | +| CUPS queue | `HP_586_MFP` (default) | +| Device URI | `ipps://192.168.88.89/ipp/print` | +| Driver | IPP Everywhere (driverless) | + +`cups-browsed` is **disabled** — it was auto-recreating an unstable mDNS-based queue whenever the printer was online. The printer is permanently saved in `/etc/cups/printers.conf` with a static IP URI. + --- ### photos VM — 192.168.88.32 (VM 113) — Photo Services @@ -190,7 +204,7 @@ Photo storage is on a local 200 GB SSD (`/mnt/immich-photos`) — migrated from ## Monitoring -Prometheus scrapes **Node Exporter** (port 9100) from every host: siklos, proxmox, Nextcloud, jellyfin, PBS, caddy, and ThinkStation. **Grafana** at `grafana.jgitta.com` visualizes all metrics and fires alerts (via Telegram) when: +Prometheus scrapes **Node Exporter** (port 9100) from every host: siklos, proxmox, Nextcloud, jellyfin, PBS, caddy, and jgpc. **Grafana** at `grafana.jgitta.com` visualizes all metrics and fires alerts (via Telegram) when: - RAM > 90% for 5 minutes - Swap > 50% for 5 minutes @@ -228,3 +242,4 @@ Prometheus scrapes **Node Exporter** (port 9100) from every host: siklos, proxmo | AI (Open WebUI) | https://ai.jgitta.com | | Guacamole | https://apache.jgitta.com | | Kopia | https://kopia.jgitta.com | + diff --git a/jellyfin/node-exporter/docker-compose.yml b/jellyfin/node-exporter/docker-compose.yml deleted file mode 100644 index 3f77805..0000000 --- a/jellyfin/node-exporter/docker-compose.yml +++ /dev/null @@ -1,15 +0,0 @@ -services: - node-exporter: - image: prom/node-exporter:latest - container_name: node-exporter - restart: unless-stopped - network_mode: host - pid: host - volumes: - - /proc:/host/proc:ro - - /sys:/host/sys:ro - - /:/rootfs:ro - command: - - '--path.procfs=/host/proc' - - '--path.sysfs=/host/sys' - - '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)' diff --git a/frigate-config.yml b/jgpc/frigate/config.yml similarity index 100% rename from frigate-config.yml rename to jgpc/frigate/config.yml diff --git a/frigate-docker-compose.yml b/jgpc/frigate/docker-compose.yml similarity index 100% rename from frigate-docker-compose.yml rename to jgpc/frigate/docker-compose.yml diff --git a/frigate-cameras.md b/jgpc/frigate/frigate-cameras.md similarity index 100% rename from frigate-cameras.md rename to jgpc/frigate/frigate-cameras.md diff --git a/jgpc/frigate/frigate-cctv-setup.md b/jgpc/frigate/frigate-cctv-setup.md new file mode 100644 index 0000000..de65600 --- /dev/null +++ b/jgpc/frigate/frigate-cctv-setup.md @@ -0,0 +1,176 @@ +# Frigate NVR & CCTV Setup + +**Last Updated:** July 2026 +**Host:** jgpc — `192.168.88.41` + +--- + +## Hardware + +| Component | Details | +|-----------|---------| +| Machine | Lenovo jgpc P710 | +| CPU | Intel Xeon E5-2623 v4 @ 2.60 GHz (4 cores / 8 threads, boost to 3.2 GHz) | +| RAM | 24 GB | +| GPU | NVIDIA GeForce GTX 1050 Ti (4 GB VRAM) | +| OS Disk | 234 GB SSD (`/dev/sda2`) | +| Media Storage | 14 TB HDD — mounted at `/mnt/14TB-HD/frigate/media` | + +--- + +## Frigate Docker Setup + +| Item | Value | +|------|-------| +| Image | `ghcr.io/blakeblackshear/frigate:stable-tensorrt` | +| Container name | `frigate` | +| Config path | `/srv/docker/frigate/config/` | +| Media path | `/mnt/14TB-HD/frigate/media` | +| Compose file | `jgpc/frigate/docker-compose.yml` (this repo) | +| Web UI | `http://192.168.88.41:5000` → `https://cameras.jgitta.com` | +| RTSP port | `8554` | +| WebRTC port | `8555` | + +**GPU acceleration:** Container runs with `runtime: nvidia` and `NVIDIA_VISIBLE_DEVICES=all`. The GTX 1050 Ti handles: +- LPR (licence plate recognition) via GPU +- Birdseye re-stream encoding via `h264_nvenc` +- ONNX object detection via the `onnx` detector + +**Shared memory:** `shm_size: 1024mb` — required for frame buffers across 6 cameras. + +--- + +## Object Detection + +| Item | Value | +|------|-------| +| Detector | ONNX (GPU-accelerated) | +| Model | YOLOv9-t-320 (`yolov9-t-320.onnx`) | +| Input size | 320 × 320 | +| Label map | COCO-80 | +| Model path | `/config/model_cache/onnx/yolov9-t-320.onnx` | + +--- + +## Licence Plate Recognition (LPR) + +| Item | Value | +|------|-------| +| Enabled | Yes | +| Device | GPU | +| Model size | Small | + +**Known plates:** + +| Name | Plate | +|------|-------| +| Joe | ABC1234 | +| Cynthia | ABC4567 | +| Wesley | XYZ9876 | + +--- + +## Camera Inventory + +All cameras are **Reolink** PoE units on the `192.168.88.0/24` subnet. + +| Camera | IP | Model notes | Mount location | +|--------|----|-------------|----------------| +| front_driveway | 192.168.88.105 | Dual-lens panoramic (7680×2160 = two 4K sensors stitched) | Front driveway | +| front_yard | 192.168.88.104 | 4K 811A | Front yard | +| shop | 192.168.88.103 | 4K 811A (uses HTTPS for API) | Shop / outbuilding | +| deck | 192.168.88.101 | 4K 811A | Deck | +| back_yard | 192.168.88.102 | 4K 811A | Back yard | +| front_right | 192.168.88.100 | 4512×2512 sensor (non-standard resolution) | Front right | + +--- + +## Camera Stream Settings + +All cameras confirmed via Reolink API (May 2026): + +| Camera | Main Resolution | Main Codec | Bitrate | FPS | I-frame | Sub Resolution | Sub Codec | +|--------|----------------|------------|---------|-----|---------|----------------|-----------| +| front_driveway (.105) | 7680×2160 | H.265 | 10240 Kbps | 20 | 1x | 1536×432 | H.264 | +| front_yard (.104) | 3840×2160 | H.265 | 6144 Kbps | 25 | 1x | 640×360 | H.264 | +| shop (.103) | 3840×2160 | H.265 | 6144 Kbps | 25 | 1x | 640×360 | H.264 | +| deck (.101) | 3840×2160 | H.265 | 6144 Kbps | 25 | 1x | 640×360 | H.264 | +| back_yard (.102) | 3840×2160 | H.265 | 6144 Kbps | 25 | 1x | 640×360 | H.264 | +| front_right (.100) | 4512×2512 | H.265 | 8192 Kbps | 20 | 1x | 896×512 | H.264 | + +**I-frame interval** set to 1x on all cameras so Frigate can start/end recording clips cleanly without waiting for a keyframe. + +--- + +## go2rtc Stream Architecture + +Chrome/Firefox cannot play H.265 (HEVC) via MSE (Media Source Extensions), so each camera requires two go2rtc streams: + +``` +camera_h265 → native H.265 RTSP from camera + └─ consumed by Frigate ffmpeg for RECORDING (stream copy, no re-encode) + +camera → ffmpeg:camera_h265#video=h264 (software H.265 → H.264 transcode) + └─ served to browser via MSE WebSocket for LIVE VIEW + +camera_sub → native low-res H.264 RTSP sub-stream + └─ consumed by Frigate for OBJECT DETECTION only +``` + +**Key behaviour notes:** +- go2rtc uses **lazy initialization** — transcoders only start when a browser opens the live view, and shut down ~30 seconds after the last viewer leaves. This causes a 2–3 second gray screen on first view, which is expected and unavoidable. +- The `_h265` streams are kept alive continuously by Frigate's recording ffmpeg processes, so recording starts instantly. +- The `#hardware` flag for NVENC transcoding in go2rtc causes EOF crashes with Reolink cameras and **must not be used**. Software transcoding (`libx264`) is used instead. +- Reolink cameras drop RTSP connections every 5–20 minutes (firmware behaviour). go2rtc reconnects automatically; this produces a brief gray screen, not static. + +### shop camera note +The shop camera (`192.168.88.103`) redirects HTTP → HTTPS. All API calls to shop must use `https://` with `-k` (skip cert verification). + +--- + +## Frigate Camera Detection Zones + +| Camera | Detect Resolution | Tracked Objects | Notes | +|--------|------------------|-----------------|-------| +| front_driveway | 1536×432 | person, car, dog, cat, license_plate | Has zone + LPR; alerts require `front_driveway_zone` | +| front_yard | 640×360 | person, car, dog, cat | — | +| shop | 640×360 | person, car, dog, cat | Motion mask on upper-right and mid-frame | +| deck | 640×360 | person, car, dog, cat | Two motion masks | +| back_yard | 640×360 | person, car, dog, cat | Two motion masks | +| front_right | 896×512 | person, car, dog, cat | Motion mask on upper-centre | + +--- + +## Recording & Retention + +| Type | Retention | +|------|-----------| +| Alert clips | 30 days | +| Detection clips | 30 days | +| Motion clips | 30 days | +| Continuous | Disabled | +| Snapshots | 30 days | + +--- + +## Known Issues & Quirks + +- **Reolink H.265 sub-stream firmware bug:** On some Reolink firmware versions, setting the sub-stream to H.265 produces a corrupted bitstream that go2rtc rejects with 404. Sub-streams should always remain H.264. +- **front_driveway panoramic:** The 7680×2160 resolution is two 4K sensors stitched side by side. The wide 1536×432 detect resolution in the Frigate config accounts for this. +- **front_right non-standard resolution:** Camera reports 4512×2512 rather than standard 4K. Model unknown — may be a 5MP variant or older sensor. +- **Swap pressure:** jgpc runs ~5.5 GB swap used under normal load. Monitor if adding more cameras or enabling Birdseye. + +--- + +## Changelog + +### 2026-07-07 — Live view fixes, audio, and two-way talk + +- **Green-box fix (front_driveway High stream):** the exec transcode crash-looped because Reolink RTSP emits corrupt HEVC frames at stream-join ("PPS changed between slices"); ffmpeg fell back to software decode and the GPU-only `scale_cuda` filter failed. Replaced with `-hwaccel cuvid -c:v hevc_cuvid -resize 3840x1080` — decode + resize stay on the GPU, no filter graph. (Also: NVENC caps H.264 at 4096 px wide, so the 7680×2160 Duo 3 main stream must be scaled before encode.) +- **front_right:** main stream is native H.264 2560×1440 — replaced NVENC transcode with direct passthrough (frees a GPU encode session). Live label renamed "High (Native)". +- **Live stream selectors:** added `live: streams:` (High/Low) to all 6 cameras to pin stream choice per device. +- **Audio:** enabled on-camera mic audio for front_driveway (Duo 3) and shop (both were off in camera firmware); front_driveway transcode now passes AAC (`-c:a copy` instead of `-an`). +- **Two-way talk (all 6 cameras):** each live go2rtc stream now has 3 sources — primary video, `ffmpeg:#audio=opus` (WebRTC audio), and `onvif://:8000` (backchannel). Added `webrtc: candidates: [192.168.88.41:8555, stun:8555]`. LAN-only unless 8555 tcp/udp is forwarded. +- **LPR:** removed `license_plate` from front_driveway tracked objects — the COCO-80 model has no such label (startup warning); LPR runs via Frigate's dedicated plate detector on `car` objects. +- **Camera-side:** Duo 3 interframe space set to 1x (gop 1) per Frigate live-view docs for faster stream startup/recovery. +- Full camera hardware specs: see `frigate-cameras.md` (this folder). diff --git a/thinkstation/open-webui/docker-compose.yml b/jgpc/open-webui/docker-compose.yml similarity index 100% rename from thinkstation/open-webui/docker-compose.yml rename to jgpc/open-webui/docker-compose.yml diff --git a/thinkstation/stirling-pdf/docker-compose.yml b/jgpc/stirling-pdf/docker-compose.yml similarity index 100% rename from thinkstation/stirling-pdf/docker-compose.yml rename to jgpc/stirling-pdf/docker-compose.yml diff --git a/owncloud/README.md b/owncloud/README.md new file mode 100644 index 0000000..a198541 --- /dev/null +++ b/owncloud/README.md @@ -0,0 +1,76 @@ +# ownCloud Photo Organizer + +## Overview + +ownCloud's Android app does not support automatic year/month subfolder creation +during instant upload (unlike Nextcloud). This script compensates by running +nightly and sorting all uploaded photos and videos into a `YEAR/YEAR-MM/` +folder structure. + +## Script + +**Location on server:** `/usr/local/bin/organize_photos.sh` + +**Source folder watched:** +`/mnt/INTEL-SSD/ownCloud - Joe Gitta@cloud.jgitta.com/Personal/InstantUpload` + +**Subfolders processed:** `Camera`, `BlueIris`, `Facebook`, `scans`, `EufyVideoDir` + +**Supported file types:** jpg, jpeg, png, gif, heic, webp, bmp, tiff, mp4, mov, pdf + +## How It Works + +The script reads the date from each filename using these patterns (in order): + +1. `YYYYMMDD` embedded in the filename (e.g. `20231022_082107.jpg`) +2. `YYYY-MM-DD` or `YYYY_MM_DD` format +3. 13-digit Unix timestamp in milliseconds (e.g. `FB_IMG_1572815868839.jpg`) +4. `MM_DD_YYYY` prefix (scans folder format, e.g. `06_11_2026_7_28_16_AM.pdf`) + +Files that don't match any pattern are moved to `_unsorted/` for manual review. + +## Output Structure + +``` +InstantUpload/ +└── Camera/ + ├── 2023/ + │ ├── 2023-06/ + │ └── 2023-12/ + ├── 2024/ + │ └── 2024-03/ + └── _unsorted/ +``` + +## Cron Job + +Runs nightly at 2:00 AM as root: + +``` +0 2 * * * /usr/local/bin/organize_photos.sh +``` + +To view or edit: `sudo crontab -e` + +## Log File + +Each run appends to `/var/log/organize_photos.log`: + +``` +=== 2026-06-14 02:00:01 Starting === + Moved: 12 Unsorted: 0 Skipped: 0 Errors: 0 +=== Done === +``` + +Check the log anytime with: +```bash +cat /var/log/organize_photos.log +``` + +## Installation + +```bash +sudo cp organize_photos.sh /usr/local/bin/organize_photos.sh +sudo chmod +x /usr/local/bin/organize_photos.sh +(sudo crontab -l; echo "0 2 * * * /usr/local/bin/organize_photos.sh") | sudo crontab - +``` diff --git a/owncloud/organize_photos.sh b/owncloud/organize_photos.sh new file mode 100755 index 0000000..81e094a --- /dev/null +++ b/owncloud/organize_photos.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash + +BASE="/mnt/INTEL-SSD/ownCloud - Joe Gitta@cloud.jgitta.com/Personal/InstantUpload" +UNSORTED="$BASE/_unsorted" +LOG="/var/log/organize_photos.log" +moved=0; skipped=0; unsorted=0; errors=0 + +echo "=== $(date +%Y-%m-%d\ %H:%M:%S) Starting ===" >> "$LOG" + +ts_to_ym() { + local ts_ms="$1" + local ts_s=$(( ts_ms / 1000 )) + date -d "@$ts_s" "+%Y %m" 2>/dev/null +} + +get_ym() { + local f="$1" + local b + b=$(basename "$f") + if [[ "$b" =~ (^|[^0-9])([0-9]{4})(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01]) ]]; then + echo "${BASH_REMATCH[2]} ${BASH_REMATCH[3]}"; return + fi + if [[ "$b" =~ ([0-9]{4})[-_](0[1-9]|1[0-2])[-_](0[1-9]|[12][0-9]|3[01]) ]]; then + echo "${BASH_REMATCH[1]} ${BASH_REMATCH[2]}"; return + fi + if [[ "$b" =~ (^|[^0-9])([0-9]{13})([^0-9]|$) ]]; then + ts_to_ym "${BASH_REMATCH[2]}"; return + fi + if [[ "$b" =~ ^([0-9]{2})_([0-9]{2})_([0-9]{4})_ ]]; then + echo "${BASH_REMATCH[3]} ${BASH_REMATCH[1]}"; return + fi + echo "" +} + +move_file() { + local src="$1" + local root="$2" + local fname + fname=$(basename "$src") + local ym + ym=$(get_ym "$src") + if [[ -z "$ym" ]]; then + mkdir -p "$UNSORTED" + if [[ ! -e "$UNSORTED/$fname" ]]; then + mv "$src" "$UNSORTED/$fname" && ((unsorted++)) || ((errors++)) + else + ((skipped++)) + fi + return + fi + local year month dest_dir dest + year=$(echo "$ym" | cut -d' ' -f1) + month=$(echo "$ym" | cut -d' ' -f2) + dest_dir="$root/$year/$year-$month" + dest="$dest_dir/$fname" + mkdir -p "$dest_dir" + if [[ -e "$dest" ]]; then + ((skipped++)); return + fi + mv "$src" "$dest" && ((moved++)) || { echo " ERROR: $fname" >> "$LOG"; ((errors++)); } +} + +for SUBDIR in Camera BlueIris Facebook scans EufyVideoDir; do + SUBPATH="$BASE/$SUBDIR" + [[ -d "$SUBPATH" ]] || continue + while IFS= read -r -d '' f; do + move_file "$f" "$SUBPATH" + done < <(find "$SUBPATH" -maxdepth 1 -type f -print0) +done + +echo " Moved: $moved Unsorted: $unsorted Skipped: $skipped Errors: $errors" >> "$LOG" +echo "=== Done ===" >> "$LOG" diff --git a/siklos/beszel/docker-compose.yml b/siklos/beszel/docker-compose.yml new file mode 100644 index 0000000..60363cf --- /dev/null +++ b/siklos/beszel/docker-compose.yml @@ -0,0 +1,27 @@ +services: + beszel: + image: henrygd/beszel:latest + container_name: beszel + restart: always + environment: + APP_URL: https://beszel.jgitta.com + ports: + - "8085:8090" + volumes: + - ./beszel_data:/beszel_data + - ./beszel_socket:/beszel_socket + + beszel-agent: + image: henrygd/beszel-agent:latest + container_name: beszel-agent + restart: always + network_mode: host + volumes: + - ./beszel_agent_data:/var/lib/beszel-agent + - ./beszel_socket:/beszel_socket + - /var/run/docker.sock:/var/run/docker.sock:ro + environment: + LISTEN: /beszel_socket/beszel.sock + HUB_URL: http://localhost:8085 + TOKEN: LNlfwOORlQXrfFFjFzjb7qCDZ4LVn-lECgkLmmwbyq8 + KEY: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF3921TigvLCBlSDqgm1bIz2To1ONUT0ahXszPTxlngU" diff --git a/siklos/monitoring/docker-compose.yml b/siklos/monitoring/docker-compose.yml deleted file mode 100644 index 26e3a16..0000000 --- a/siklos/monitoring/docker-compose.yml +++ /dev/null @@ -1,65 +0,0 @@ -services: - prometheus: - image: prom/prometheus:latest - container_name: prometheus - restart: unless-stopped - ports: - - "9090:9090" - volumes: - - /srv/docker/monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro - - prometheus_data:/prometheus - command: - - "--config.file=/etc/prometheus/prometheus.yml" - - "--storage.tsdb.path=/prometheus" - - "--storage.tsdb.retention.time=30d" - - "--web.enable-lifecycle" - - "--web.enable-admin-api" - - grafana: - image: grafana/grafana:latest - container_name: grafana - restart: unless-stopped - ports: - - "3020:3000" - volumes: - - grafana_data:/var/lib/grafana - environment: - - GF_SECURITY_ADMIN_USER=admin - - GF_SECURITY_ADMIN_PASSWORD=Jogiocsi1211+ - - GF_USERS_ALLOW_SIGN_UP=false - - FTLCONF_dns_maxConcurrentQueries=300 - depends_on: - - prometheus - - cadvisor: - image: gcr.io/cadvisor/cadvisor:latest - container_name: cadvisor - restart: unless-stopped - privileged: true - ports: - - "8090:8080" - volumes: - - /:/rootfs:ro - - /var/run:/var/run:ro - - /sys:/sys:ro - - /var/lib/docker:/var/lib/docker:ro - - /dev/disk/:/dev/disk:ro - - graphite-exporter: - image: prom/graphite-exporter:latest - container_name: graphite-exporter - restart: unless-stopped - ports: - - "9109:9109" - - "9109:9109/udp" - - "9108:9108" - volumes: - - /srv/docker/monitoring/graphite/graphite_mapping.conf:/tmp/graphite_mapping.conf:ro - command: - - "--graphite.mapping-config=/tmp/graphite_mapping.conf" - - "--graphite.listen-address=:9109" - - "--web.listen-address=:9108" - -volumes: - prometheus_data: - grafana_data: diff --git a/thinkstation/frigate/docker-compose.yml b/thinkstation/frigate/docker-compose.yml deleted file mode 100644 index b7e5472..0000000 --- a/thinkstation/frigate/docker-compose.yml +++ /dev/null @@ -1,35 +0,0 @@ -services: - frigate: - container_name: frigate - image: ghcr.io/blakeblackshear/frigate:stable-tensorrt - privileged: true - shm_size: "1024mb" - restart: always - runtime: nvidia - environment: - - NVIDIA_VISIBLE_DEVICES=all - - NVIDIA_DRIVER_CAPABILITIES=compute,video,utility - - FRIGATE_RTSP_PASSWORD=restreampass - secrets: - - frigate_jwt_secret - deploy: - resources: - reservations: - devices: - - driver: nvidia - count: 1 - capabilities: [gpu, compute, video] - volumes: - - /srv/docker/frigate/config:/config - - /mnt/14TB-HD/frigate/media:/media/frigate - - /etc/localtime:/etc/localtime:ro - ports: - - "5000:5000" - - "8971:8971" - - "8554:8554" - - "8555:8555/tcp" - - "8555:8555/udp" - -secrets: - frigate_jwt_secret: - file: /srv/docker/frigate/config/jwt_secret