5d7c8ea030
- gitea: LevelDB queues -> local /var/lib/gitea-queues (stale NFS lock, 7,972-restart loop) - semaphore-db: data -> local /var/lib/semaphore-db (stale ibdata1 NFS lock, 975 restarts) - sonarr: config -> local /var/lib/sonarr (SQLite-on-NFS migration crash) - nzbhydra2: mem_limit 768M -> 1G (was pinned at limit, unhealthy) - jellyfin: deploy pending VAAPI device passthrough (i965/renderD128) - openvas: disable Watchtower (latest major pull forced pg_upgrade crash-loop) - onyx: fully decommissioned (down since ~June 8 unnoticed) - remove duplicate monitoring/traefik/guacamole stacks from .100, failover guacamole from bart - synapse: raise rc_message (alertmanager receiver was 429-limited; alerts silently dropped for weeks) - prometheus: UniFi probe 8443 -> 11443, solo.hobbs.farm via 401-tolerant module, drop onyx target - frigate restart cron: unwritable /var/log path meant it never ran; now 4x daily to ~glyptic - CLAUDE.md: document all of the above + AdGuard broken/unconfigured since 2026-05-17 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
313 lines
21 KiB
Markdown
313 lines
21 KiB
Markdown
# CLAUDE.md
|
||
|
||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||
|
||
## Repository Overview
|
||
|
||
This repository manages a **homelab infrastructure** with self-hosted services running across 3 nodes using **standalone Docker Compose** on all nodes. (Docker Swarm was fully dismantled on 2026-04-01.)
|
||
|
||
### Cluster Architecture
|
||
|
||
**Nodes:**
|
||
- **hf-pdocker-01** (192.168.86.192) - Core infrastructure + Frigate NVR - **RESTORED (2026-03-08)**
|
||
- **hf-pdocker-02** (192.168.86.100) - Dev tools, utilities
|
||
- **bart** (192.168.86.167) - Media stack, OpenVAS
|
||
|
||
**Synology NAS** (192.168.86.30) - Centralized NFS storage for all service data
|
||
|
||
**Access:** Username `glyptic`, password `&Rip8a115` (has sudo access on all nodes)
|
||
|
||
### Service Distribution
|
||
|
||
```
|
||
hf-pdocker-01 (23GB RAM, i7-7700T, NVMe, HD 630 GPU) -- RESTORED (2026-03-08, hardware repaired)
|
||
├── [COMPOSE] Frigate NVR (:5000) -- Coral USB TPU (edgetpu), ~11ms inference, 13 cameras active
|
||
├── [COMPOSE] Frigate-Notify v2 (:5199) -- MQTT->AI->Matrix notifications
|
||
├── [COMPOSE] clip-service (:5200) -- CLIP embeddings (ViT-L-14, CPU)
|
||
├── [COMPOSE] Home Assistant (:8123)
|
||
├── [COMPOSE] ESPHome (:6052)
|
||
├── [COMPOSE] Mosquitto (:1883, :8883)
|
||
├── [COMPOSE] Synapse/Matrix (:8008) + synapse-db (postgres) + wellknown (:8010)
|
||
├── [COMPOSE] Guacamole (:8199) + guacd + guacamole-db (mysql, LOCAL /var/lib/guacamole-db)
|
||
├── [COMPOSE] AI Agents (margaret:18790, spirit:18795 [infra ops])
|
||
├── [COMPOSE] Traefik (reverse proxy, ports 80/443/8090)
|
||
├── [COMPOSE] AdGuard Home (:3000, :53) -- **BROKEN since 2026-05-17**: conf dir empty, stuck in first-run wizard, DNS not answering. No backup found; needs manual reconfigure via :3000/install.html.
|
||
├── [COMPOSE] Monitoring (Grafana :3001, Prometheus :9095, Alertmanager :9093, InfluxDB :8086, Blackbox :9115, matrix-receiver :9094)
|
||
├── [COMPOSE] Farm Manager API (:8888) -- dashboard + API server
|
||
├── [COMPOSE] Farm Agent (:8889)
|
||
├── [COMPOSE] Rongorongo decipherment engine -- 2 containers (rongorongo-web :8181, rongorongo-api). Server-synced state at /mnt/docker-data/configs/rongorongo/data. Traefik basicAuth on rongorongo.hobbs.farm.
|
||
├── [COMPOSE] LinkedStorm (:8300 pipeline, :8310 api, cron no-port) -- whole-home audio assistant. VAD+Whisper STT+speaker-ID. Deployed 2026-05-28. Public: linkedstorm.hobbs.farm -> :8310.
|
||
├── [REMOVED] VoiceCoach -- moved to GPU machine (192.168.86.150) 2026-04-04
|
||
├── [COMPOSE] litellm (:4000?) + litellm-db -- LLM proxy (see Known Issue #15)
|
||
├── [COMPOSE] synapse-admin -- Synapse admin UI
|
||
├── [COMPOSE] Node-exporter (:9100) -- standalone with pid:host
|
||
├── [COMPOSE] Telegraf -- metrics collection to InfluxDB
|
||
├── [CRON] sync-frigate-to-nas (daily 2am), cleanup-frigate-media (weekly Sun 3am), restart-frigate (4x daily 4am/10am/4pm/10pm, log ~/frigate-restart.log)
|
||
├── 5TB USB disk at /mnt/frigate-recordings (Frigate recordings storage)
|
||
|
||
bart (15GB RAM, i5-4570T, HDD)
|
||
├── [COMPOSE] Media Stack (Jellyfin, Sonarr, Radarr, SABnzbd, NZBHydra2, Jellyseerr) -- Sonarr config on LOCAL /var/lib/sonarr (2026-07-13, SQLite-on-NFS crash)
|
||
├── [REMOVED] Onyx -- fully decommissioned 2026-07-13 (had been down since ~2026-06-08 unnoticed; containers, volumes, images removed)
|
||
├── [COMPOSE] OpenVAS (vulnerability scanner) -- Watchtower disabled 2026-07-13 after :latest major pull forced pg_upgrade crash-loop
|
||
├── [COMPOSE] Farm Agent (:8889)
|
||
├── [COMPOSE] Node-exporter (:9100) -- standalone with pid:host
|
||
├── [COMPOSE] Telegraf -- metrics collection to InfluxDB
|
||
├── [COMPOSE] Watchtower
|
||
|
||
hf-pdocker-02 (7.6GB RAM, i7-6700T, HDD)
|
||
├── [COMPOSE] UniFi OS Server (container `unifi-os-server`, HTTPS on host :11443)
|
||
├── [COMPOSE] Gitea + gitea-db (PostgreSQL) -- LevelDB queues on LOCAL /var/lib/gitea-queues (2026-07-13, stale NFS lock caused 7,972-restart loop)
|
||
├── [COMPOSE] Semaphore + semaphore-db (MySQL, LOCAL /var/lib/semaphore-db since 2026-07-13)
|
||
├── [COMPOSE] Wiki.js + wikijs-db (PostgreSQL)
|
||
├── [COMPOSE] Vaultwarden, Actual Budget, MCPO, Trivy
|
||
├── [COMPOSE] n8n + n8n-db (PostgreSQL) -- workflow automation
|
||
├── [COMPOSE] CouchDB (:5984) -- Obsidian LiveSync backend for the Second Brain vault. LAN-only. LOCAL disk (NOT NFS).
|
||
├── [COMPOSE] Farm Agent (:8889)
|
||
├── [COMPOSE] Node-exporter (:9100) -- standalone with pid:host
|
||
├── [COMPOSE] Telegraf -- metrics collection to InfluxDB
|
||
├── [COMPOSE] Watchtower
|
||
|
||
```
|
||
|
||
## Working with This Repository
|
||
|
||
### Environment Context
|
||
|
||
You are working in a **WSL 2 environment** on Windows. Docker is NOT directly available in WSL - all Docker operations must be performed by connecting to the remote nodes via SSH.
|
||
|
||
**Critical:** Docker is not available locally in WSL. All Docker operations must be performed by connecting to the remote nodes via SSH.
|
||
|
||
### Storage Architecture
|
||
|
||
All service data lives on the **Synology NAS** via NFS, mounted at `/mnt/docker-data` on all 3 nodes.
|
||
|
||
```
|
||
/mnt/docker-data/ (NAS: 192.168.86.30:/volume1/Docker)
|
||
├── configs/ # Application configs
|
||
├── databases/ # Database data directories
|
||
├── media/ # Frigate recordings
|
||
├── traefik/ # Let's Encrypt certs
|
||
└── compose/ # Standalone compose files per node
|
||
├── hf-pdocker-01/{frigate,frigate-notify,clip-service,matrix,smarthome,guacamole,ai-agents,traefik,adguard}/
|
||
├── hf-pdocker-02/{unifi,gitea,semaphore,wikijs,vaultwarden,actual-budget,mcpo,trivy,watchtower}/
|
||
└── bart/{media,openvas,watchtower}/
|
||
```
|
||
|
||
**NFS mount (all nodes):** `192.168.86.30:/volume1/Docker /mnt/docker-data nfs rw,soft,timeo=300,intr,_netdev,nfsvers=3,nofail,x-systemd.after=network-online.target,x-systemd.mount-timeout=60s 0 0`
|
||
**Note (hf-pdocker-01):** Both NFS mounts hardened with `nofail,x-systemd.after=network-online.target,x-systemd.mount-timeout=60s` on 2026-05-20 to prevent boot-time race (network not up when NFS tried to mount, cascading ~10 container failures).
|
||
|
||
**NFS + Databases:** Database containers on NFS require `user: "1024:100"` to avoid `chown` failures from NFS root_squash. UID 1024 is the NAS anonymous user.
|
||
|
||
### Repository File Structure
|
||
|
||
```
|
||
stacks/ # LEGACY Swarm stack definitions (Swarm dismantled 2026-04-01, kept for reference)
|
||
|
||
compose/ # Standalone Compose definitions (deployed per-node)
|
||
├── hf-pdocker-01/ # Core infrastructure + Frigate
|
||
├── hf-pdocker-02/ # Dev tools & utilities
|
||
│ ├── {service}/docker-compose.yml
|
||
│ └── {service}/.env
|
||
└── bart/ # Media stack & OpenVAS
|
||
```
|
||
|
||
### Deployment Workflow
|
||
|
||
**All services (compose/):**
|
||
1. Edit compose file in `compose/{node}/{service}/docker-compose.yml`
|
||
2. SCP to NAS path or node, then: `cd /mnt/docker-data/compose/{node}/{service} && docker compose up -d`
|
||
|
||
### Service Architecture Patterns
|
||
|
||
**Network Patterns:**
|
||
- **Compose services**: Bridge networks for service isolation
|
||
- **Public services** (Traefik): Traefik labels + dynamic config files in `/mnt/docker-data/traefik/dynamic/`
|
||
|
||
**Database Patterns:**
|
||
- PostgreSQL: `postgres:15-alpine` or `postgres:16-alpine`
|
||
- MySQL: `mysql:8.0` (Guacamole, Semaphore)
|
||
- MongoDB: `mongo:7.0` (Unifi)
|
||
- **Always** add `com.centurylinklabs.watchtower.enable=false` label
|
||
- **Always** add `user: "1024:100"` for NFS-backed database volumes
|
||
|
||
**Volume Patterns:**
|
||
- Application data: `/mnt/docker-data/configs/{service-name}/`
|
||
- Database data: `/mnt/docker-data/databases/{service-name}-db/`
|
||
- Traefik certs: `/mnt/docker-data/traefik/letsencrypt/`
|
||
|
||
## Key Services & Access
|
||
|
||
### Public Services (via Traefik on hf-pdocker-01)
|
||
|
||
- Matrix: `mess.hobbs.farm`
|
||
- Guacamole: `solo.hobbs.farm`
|
||
- Home Assistant: `yoda.hobbs.farm`
|
||
- Vaultwarden: `vault.hobbs.farm`
|
||
- Gitea: `git.hobbs.farm`
|
||
- FRIDAY Voice: `coach.hobbs.farm` (replaced VoiceCoach 2026-07-05; runs on .150 :8320)
|
||
- Rongorongo: `rongorongo.hobbs.farm`
|
||
- LinkedStorm: `linkedstorm.hobbs.farm`
|
||
|
||
### Internal Services by Node
|
||
|
||
**hf-pdocker-01 (192.168.86.192):**
|
||
- Frigate: :5000
|
||
- Frigate Alerts (v2): :5199 (web UI + REST API)
|
||
- clip-service: :5200 (CLIP embeddings, ViT-L-14, CPU)
|
||
- Home Assistant: :8123
|
||
- ESPHome: :6052
|
||
- Mosquitto: :1883
|
||
- Matrix/Synapse: :8008
|
||
- Well-known (Matrix federation): :8010
|
||
- Guacamole: :8199
|
||
- AdGuard Home: :3000 (DNS: :53)
|
||
- Traefik Dashboard: :8090 (HTTP: :80, HTTPS: :443)
|
||
- Grafana: :3001
|
||
- Prometheus: :9095
|
||
- Alertmanager: :9093
|
||
- InfluxDB: :8086
|
||
- Blackbox Exporter: :9115
|
||
- matrix-alertmanager-receiver: :9094
|
||
- AI Agents (margaret :18790, spirit :18795 [infra ops — monitors #notifications, auto-remediates alerts]) -- LAN-accessible (bind=lan, 0.0.0.0)
|
||
- Farm Manager: :8888 (dashboard + API)
|
||
- Farm Agent: :8889
|
||
- Rongorongo: :8181 (rongorongo-web nginx; reverse-proxies /api/* to rongorongo-api Flask backend on the internal `rongorongo` bridge net). State + images at /mnt/docker-data/configs/rongorongo/data/. Public URL gated by Traefik basicAuth (creds in Vaultwarden).
|
||
- LinkedStorm: :8300 (pipeline/VAD+STT+speaker-ID), :8310 (API/dashboard), cron (no port). Public: linkedstorm.hobbs.farm -> :8310. Source: /opt/linkedstorm (rsync from WSL). Data: /mnt/docker-data/configs/linkedstorm/. STT via Speaches GPU machine :8000, LLM via Ollama :11434 (qwen2.5:14b).
|
||
- ~~VoiceCoach~~ -- fully decommissioned 2026-07-05, replaced by FRIDAY Voice on .150 (see GPU Machine section + memory `friday-voice`)
|
||
|
||
**hf-pdocker-02 (192.168.86.100):**
|
||
- Farm Agent: :8889
|
||
- UniFi OS Server: :11443 (HTTPS, container 443)
|
||
- Gitea: :3003 (web), :2222 (SSH)
|
||
- Semaphore: :3004
|
||
- Wiki.js: :3002
|
||
- Vaultwarden: :26226
|
||
- Actual Budget: :5006
|
||
- MCPO: :8001
|
||
- Trivy: :4954
|
||
- CouchDB: :5984 -- Obsidian LiveSync backend. DB `secondbrain`; admin creds in Vaultwarden ("CouchDB - Obsidian LiveSync"). LAN-only (no Traefik route). Data on LOCAL disk `/var/lib/couchdb` (NFS breaks CouchDB file locking). **`local.ini` must be mounted READ-WRITE** -- with `:ro` CouchDB exits 1 and logs nothing. Auth required on everything except `/_up` (left open for the blackbox probe). Vault repo: git.hobbs.farm/jeremy/second-brain (private); vault lives at `C:\Users\Jeremy\second-brain` on the Windows box.
|
||
|
||
**bart (192.168.86.167):**
|
||
- Farm Agent: :8889
|
||
- Jellyfin: :8096
|
||
- Sonarr: :8989
|
||
- Radarr: :7878
|
||
- SABnzbd: :8082
|
||
- NZBHydra2: :5076
|
||
- Jellyseerr: :5055
|
||
- OpenVAS: :9392
|
||
|
||
**GPU Machine (192.168.86.150, RTX 3090):**
|
||
- **NOTE (2026-07-05):** .150 is actually the user's **Windows workstation** (runs the WSL/Claude Code session), not a headless Linux server. It runs **Docker Desktop** (WSL2 backend, RTX 3090 GPU passthrough working) alongside **UniFi OS Server** (Podman). Docker Desktop panics if UniFi/Podman claims `\\.\pipe\docker_engine` first — start Docker Desktop before UniFi OS Server. See memory `docker-desktop-unifi-podman-conflict`.
|
||
- **FRIDAY Voice replaced VoiceCoach (2026-07-05).** VoiceCoach fully decommissioned (v1+v2 removed from hf-pdocker-01; voice.hobbs.farm route removed). See memory `friday-voice`.
|
||
- [COMPOSE] **FRIDAY Voice stack (all on .150 Docker Desktop, via `docker.exe -c desktop-linux`):**
|
||
- **voicecoach-speaches-gpu**: :8000 — GPU Whisper large-v3-turbo (STT) + Kokoro-82M af_nova (TTS), CUDA float16. Compose: `compose/gpu-machine/voicecoach-speaches/`.
|
||
- **hermes**: `nousresearch/hermes-agent:latest` gateway — FRIDAY's reasoning agent. Settings transferred from WSL `~/.hermes` into named volume `hermes-data`. Compose: `compose/gpu-machine/hermes/`.
|
||
- **friday-voice**: :8320 — push-to-talk console. Calls speaches (`host.docker.internal:8000`) + hermes (`docker exec hermes hermes -Q` via wrapper). Public: **coach.hobbs.farm** → :8320. Compose: `compose/gpu-machine/friday-voice/`.
|
||
- Ollama: :11434 (qwen2.5:14b, Hermes-4.3-36B-GGUF, others)
|
||
|
||
### Port Conflict Notes
|
||
|
||
Port conflicts already resolved:
|
||
- Port 8000: Freed (MCPO moved to 8001, Portainer moved elsewhere)
|
||
- Port 3000: AdGuard Home (Gitea moved to 3003)
|
||
- Port 3001: Grafana (Semaphore moved to 3004)
|
||
- Port 5000: Frigate uses host networking (registry container stopped)
|
||
- AI Agent ports re-spaced (2026-03-15): openclaw 2026.3.13 uses gateway+2 and gateway+3 for browser/chrome-relay. Agents spaced 5 apart: margaret=18790, spirit=18795
|
||
|
||
## Critical Configuration Preservation
|
||
|
||
### Encryption Keys & Passwords
|
||
|
||
- Semaphore: `SEMAPHORE_ACCESS_KEY_ENCRYPTION` encrypts sensitive data
|
||
- **Always** check for existing encryption keys before generating new ones
|
||
|
||
### Database Version Matching
|
||
|
||
Match the PostgreSQL/MySQL version to existing data directory format. Check logs for version mismatch errors.
|
||
|
||
## Post-Change Checklist (MANDATORY)
|
||
|
||
After ANY infrastructure change (deploy, remove, reconfigure, add service, change ports, modify Traefik routes), you MUST complete ALL of these before reporting done:
|
||
|
||
1. **CLAUDE.md** — Update service lists, ports, node assignments if changed
|
||
2. **MEMORY.md** — Add/update relevant memory entries
|
||
3. **Prometheus probes** — Add/remove blackbox targets, hot-reload Prometheus
|
||
4. **Wiki** — Launch documentation-keeper agent to update wiki pages (run in background)
|
||
|
||
Do NOT wait for the user to ask. Do NOT skip "because the change was small." Every change gets documented.
|
||
|
||
## Common Operations
|
||
|
||
### Deploy/Update a Compose Service
|
||
|
||
1. Edit `compose/{node}/{service}/docker-compose.yml`
|
||
2. SSH to the target node and run:
|
||
```bash
|
||
cd /mnt/docker-data/compose/{node}/{service}
|
||
docker compose up -d
|
||
```
|
||
|
||
### Troubleshoot
|
||
|
||
```bash
|
||
# On target node:
|
||
docker compose -f /mnt/docker-data/compose/{node}/{service}/docker-compose.yml logs --tail 100
|
||
docker ps --format "table {{.Names}}\t{{.Status}}"
|
||
```
|
||
|
||
### Check Cluster Health
|
||
|
||
```bash
|
||
# On each node:
|
||
docker ps # Local containers
|
||
```
|
||
|
||
## Data Management
|
||
|
||
### Storage
|
||
|
||
All persistent data on NAS at `/mnt/docker-data/`:
|
||
- `configs/` - Application configurations
|
||
- `databases/` - Database volumes
|
||
- `media/` - Frigate recordings
|
||
- `traefik/` - SSL certificates
|
||
|
||
### NAS Dependency
|
||
|
||
**Risk**: NAS failure = all services fail (single point of failure)
|
||
- NFS mount uses `soft,timeo=300` for graceful timeout
|
||
- Synology should have "Restart automatically after power failure" enabled
|
||
- Original data backups remain on local `/data/configs/` on hf-pdocker-01
|
||
|
||
## Specialized Agents
|
||
|
||
### vault-credential-manager
|
||
**Use for:** Storing/retrieving credentials from Vaultwarden
|
||
|
||
### documentation-keeper
|
||
**Use for:** Creating/updating documentation in Wiki.js
|
||
|
||
## Known Issues & Workarounds
|
||
|
||
1. **NFS root_squash**: Database containers need `user: "1024:100"` to avoid chown failures on NAS volumes
|
||
2. **Telegraf Docker Input**: Disabled due to Docker socket permission issues across nodes
|
||
3. **Watchtower API Version**: Requires `DOCKER_API_VERSION=1.44`
|
||
4. **InfluxDB Connection**: Telegraf may show timeout errors if InfluxDB is not running
|
||
5. **Frigate cameras**: Cameras on 192.168.44.x subnet may show RTSP timeouts (check camera network)
|
||
6. **Registry container**: Stopped on hf-pdocker-01 to free port 5000 for Frigate
|
||
7. **systemd-resolved DNSStubListener**: Must be disabled on any node running AdGuard Home (port 53 conflict). Fix: `/etc/systemd/resolved.conf.d/nostub.conf` with `DNSStubListener=no`, then `systemctl restart systemd-resolved`. Applied on hf-pdocker-01 and hf-pdocker-02.
|
||
8. **NFS boot-mount race (hf-pdocker-01)**: NFS mounts failed at boot (network not ready in time). Fixed 2026-05-20 by adding `nofail,x-systemd.after=network-online.target,x-systemd.mount-timeout=60s` to both fstab entries. If mounts are missing after reboot: `sudo mount /mnt/docker-data && sudo mount /mnt/infrastructure`.
|
||
9. **Guacamole schema**: App image pinned to `guacamole/guacamole:1.6.0` + `guacd:1.6.0` with Watchtower disabled. DB schema was reset to fresh 1.6.0 on 2026-05-20 (old schema was non-standard). Recreate connections after any DB reset.
|
||
10. **Gitea image**: Pinned to `gitea/gitea:1.26.1` with Watchtower disabled (2026-05-20). Watchtower previously pulled broken `:latest` images causing missing git binary errors.
|
||
11. **Home Assistant reverse proxy**: Config at `/mnt/docker-data/configs/homeassistant/configuration.yaml` (no hyphen). Must have `http: use_x_forwarded_for: true` + `trusted_proxies: [172.16.0.0/12, 127.0.0.1]` or proxied requests return 400.
|
||
12. **hf-pdocker-01 memory pressure (2026-07-05, retrimmed 2026-07-11)**: Node runs hot (~15-18/23GB, chronic swap). Mitigations applied: `vm.swappiness` lowered 60→10 (persisted in `/etc/sysctl.d/99-swappiness.conf`), and VoiceCoach (v1+v2, ~10 containers) fully removed (replaced by FRIDAY Voice on .150). Frigate is the main consumer. **2026-07-11:** Frigate's built-in AI features (`semantic_search: large`, `face_recognition`, `lpr`, `classification.bird`) were found *enabled* (contradicting the intended baseline) and re-disabled — dropped the embeddings CLIP model ~1.2GB→168MB and cut CPU inference; host mem 18→~9GB, swap 3.9→1.3GB right after. Config `/mnt/docker-data/configs/frigate/config/config.yml` (backup `.bak.20260711-aitrim`). Recognition is instead handled externally by clip-service + frigate-notify v2. **2026-07-12 — WHOLE-NODE CRASH:** .192 froze hard (~14:15, sshd/HA/DNS all dead, required hard reboot). Cause: Frigate `memswap_limit` had drifted to **16G** vs `mem_limit` 12G, letting it spill ~4GB into host swap; with the ffmpeg leak pinning it at 12G all day (cgroup OOM every ~45min), the host swap-thrashed to death. **Fix: node compose `memswap_limit: 12G` (= mem_limit) so Frigate can never use host swap** — a hit now trims its own ffmpeg (contained cgroup OOM), not the host. Repo already had 12G; node had drifted (never redeployed). NOTE: recording ffmpeg still leaks ~0.8GB/h atop ~6GB baseline (fills 12G in ~7.5h); twice-daily 4am+4pm restart-frigate cron mitigates but doesn't fully beat it — consider every-6h restart + fixing broken cameras (gate_camera, garage_2). Always keep `memswap_limit == mem_limit` on this node.
|
||
13. **Docker Desktop vs UniFi OS Server pipe conflict (Windows box .150, 2026-07-05)**: Both fight over `\\.\pipe\docker_engine`; Docker Desktop's backend nil-panics ("backend exited before becoming ready") if Podman wins. Fix: let Docker Desktop (auto-starts at login) claim the pipe first, launch UniFi OS Server manually after. Full detail in memory `docker-desktop-unifi-podman-conflict`.
|
||
14. **MySQL InnoDB corruption on NFS**: `semaphore-db` (mysql:8.0 on NFS) hit system-tablespace page corruption and crash-looped 3789× (2026-07-11), same class as the Guacamole-on-NFS issue (#9). Recovered in-place via `--innodb-force-recovery=1` → mysqldump → fresh volume → reimport (DB was empty, no data lost); admin recreated with `semaphore user add`. Any MySQL DB on NFS is at risk — prefer LOCAL storage like guacamole-db. See memory `semaphore-db-nfs-corruption`.
|
||
15. **litellm hangs after DB blip**: litellm does NOT self-recover from a transient `litellm-db` disconnect — it loops on "Prisma DB reconnect failed" forever; needs manual `docker restart litellm`. Its healthcheck was fixed from `curl` (absent from image, permanent false-unhealthy) to a python urllib check (2026-07-11).
|
||
16. **Stale NFS locks after unclean reboot/power loss (2026-07-12 power event)**: NFS file locks held by pre-reboot client identities survive on the Synology and block relocking — gitea crash-looped 7,972× on its LevelDB queue lock, semaphore-db 975× on `ibdata1`. Fix applied 2026-07-13: lock-prone data moved to LOCAL disk (gitea queues → `/var/lib/gitea-queues`, semaphore-db → `/var/lib/semaphore-db` on .100; sonarr config → `/var/lib/sonarr` on bart). **Rule: anything holding long-lived file locks (MySQL, SQLite, LevelDB) goes on local disk, never NFS.**
|
||
17. **Synapse rate-limited Alertmanager notifications**: default `rc_message` (0.2 msg/s) made every matrix-alertmanager-receiver send fail with M_LIMIT_EXCEEDED 429 — **no alerts reached Matrix for weeks** while outages accumulated (Onyx down 5 weeks, AdGuard dead 2 months, unnoticed). Fixed 2026-07-13: `rc_message: {per_second: 5, burst_count: 50}` in homeserver.yaml (backup `.bak-20260713-ratelimit`).
|
||
18. **AdGuard Home unconfigured since 2026-05-17**: its conf dir (`/mnt/docker-data/configs/adguardhome/conf`) is empty — container runs the first-launch wizard and serves NO DNS. No AdGuardHome.yaml backup exists anywhere. LAN DNS has been coming from elsewhere (router) since May. Needs manual re-setup at http://192.168.86.192:3000.
|
||
19. **Duplicate failover stacks removed from .100 and bart (2026-07-13)**: .100 ran a second monitoring stack (prometheus/grafana/alertmanager/influxdb/blackbox), an idle traefik (shared acme.json with .192 — ACME conflict risk), and a stray guacamole; bart ran a failover guacamole. All removed (~2GB RAM reclaimed). Compose dirs kept for reference; data volumes untouched.
|
||
20. **UniFi OS Server probe port**: `unifi-os-server` on .100 serves HTTPS on host port **11443** (container 443), not 8443. Blackbox probe fixed 2026-07-13. solo.hobbs.farm returns 401 (Traefik basicAuth) when healthy — probed via `http_2xx_or_401` module.
|