de1d9e1d93
Replaces initial Nomad/Consul/Terraform skeleton with current Docker-based infrastructure across all three nodes (hf-pdocker-01, hf-pdocker-02, bart). Key changes: - CLAUDE.md: updated service distribution reflecting hf-pdocker-01 restored - docs/plans/2026-03-08-hf-pdocker-01-rebuild.md: new rebuild plan doc - compose/bart/: ai-agents, guacamole, matrix, media, openvas, smarthome, watchtower - compose/hf-pdocker-02/: traefik, monitoring, adguard, gitea, semaphore, wikijs, unifi, vaultwarden, actual-budget, mcpo, netclaw, trivy, watchtower, n8n - compose/hf-pdocker-01/: frigate, frigate-notify, farm-agent - stacks/: all Swarm stack definitions (monitoring, traefik, smarthome, matrix, guacamole, media, ai-agents, frigate, gitea, semaphore, wikijs, unifi, etc.) - .gitignore: exclude .env credential files and acme.json certs - .env.example: placeholder credential files for all services - .claude/agents/: gitea-backup and other infrastructure agent configs - scripts/: frigate media cleanup and NAS sync scripts Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
429 lines
12 KiB
Markdown
429 lines
12 KiB
Markdown
# hf-pdocker-01 Rebuild — Phase 1 Implementation Plan
|
|
|
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
|
|
|
**Goal:** Rebuild hf-pdocker-01 from fresh Ubuntu 24.04 to a fully operational Swarm manager with Frigate NVR, Farm Agent, and Frigate-Notify v2.
|
|
|
|
**Architecture:** Fresh Ubuntu 24.04 on NVMe, Docker CE, NFS-backed storage from Synology NAS, 5TB USB disk for Frigate recordings. Docker Swarm re-initialized as single manager with hf-pdocker-02 and bart rejoined as workers. Services deployed via Compose files already on NAS.
|
|
|
|
**Tech Stack:** Ubuntu 24.04, Docker CE, Docker Swarm, NFS v3, Intel VA-API/OpenVINO, Python 3.12 (containers)
|
|
|
|
**Access:** SSH to hf-pdocker-01 (192.168.86.192), user `glyptic`, password `&Rip8a115`
|
|
|
|
**Important:** All tasks execute via SSH from the WSL environment. Use the `docker-swarm-ops` agent for all remote operations.
|
|
|
|
---
|
|
|
|
### Task 1: Install System Prerequisites
|
|
|
|
**Target:** hf-pdocker-01 (192.168.86.192)
|
|
|
|
**Step 1: Install base packages**
|
|
|
|
```bash
|
|
sudo apt-get update
|
|
sudo apt-get install -y nfs-common curl jq git rsync
|
|
```
|
|
|
|
**Step 2: Install Docker CE**
|
|
|
|
```bash
|
|
# Add Docker GPG key and repo
|
|
sudo install -m 0755 -d /etc/apt/keyrings
|
|
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
|
sudo chmod a+r /etc/apt/keyrings/docker.gpg
|
|
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
|
sudo apt-get update
|
|
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
|
```
|
|
|
|
**Step 3: Add glyptic to docker group**
|
|
|
|
```bash
|
|
sudo usermod -aG docker glyptic
|
|
```
|
|
|
|
**Step 4: Install Intel VA-API drivers for Frigate OpenVINO**
|
|
|
|
```bash
|
|
sudo apt-get install -y intel-media-va-driver-non-free vainfo
|
|
```
|
|
|
|
**Step 5: Verify**
|
|
|
|
```bash
|
|
docker --version # Expect: Docker version 28.x
|
|
docker compose version # Expect: Docker Compose version v2.x
|
|
vainfo # Expect: VA-API device listed (iHD driver, HD 630)
|
|
ls /dev/dri/ # Expect: card0, renderD128
|
|
```
|
|
|
|
---
|
|
|
|
### Task 2: Configure System Settings
|
|
|
|
**Target:** hf-pdocker-01 (192.168.86.192)
|
|
|
|
**Step 1: Set vm.swappiness to 10 (cluster standard)**
|
|
|
|
```bash
|
|
echo "vm.swappiness=10" | sudo tee -a /etc/sysctl.conf
|
|
sudo sysctl vm.swappiness=10
|
|
```
|
|
|
|
**Step 2: Verify**
|
|
|
|
```bash
|
|
sysctl vm.swappiness # Expect: vm.swappiness = 10
|
|
```
|
|
|
|
---
|
|
|
|
### Task 3: Configure NFS Mounts
|
|
|
|
**Target:** hf-pdocker-01 (192.168.86.192)
|
|
|
|
**Step 1: Create mount points**
|
|
|
|
```bash
|
|
sudo mkdir -p /mnt/docker-data /mnt/infrastructure
|
|
```
|
|
|
|
**Step 2: Add NFS entries to fstab**
|
|
|
|
```bash
|
|
echo '192.168.86.30:/volume1/Docker /mnt/docker-data nfs rw,soft,timeo=300,intr,_netdev,nfsvers=3 0 0' | sudo tee -a /etc/fstab
|
|
echo '192.168.86.30:/volume1/Infrastructure /mnt/infrastructure nfs rw,hard,intr,_netdev 0 0' | sudo tee -a /etc/fstab
|
|
```
|
|
|
|
**Step 3: Mount and verify**
|
|
|
|
```bash
|
|
sudo mount -a
|
|
ls /mnt/docker-data/configs/ # Expect: frigate, frigate-notify, etc.
|
|
ls /mnt/infrastructure/margaret/ # Expect: openclaw.json, credentials/, etc.
|
|
```
|
|
|
|
---
|
|
|
|
### Task 4: Mount 5TB Frigate Recordings Disk
|
|
|
|
**Target:** hf-pdocker-01 (192.168.86.192)
|
|
|
|
**Step 1: Identify the disk and verify existing data**
|
|
|
|
```bash
|
|
sudo blkid /dev/sda1 # Check filesystem type (expect ext4)
|
|
sudo mkdir -p /mnt/frigate-recordings
|
|
sudo mount /dev/sda1 /mnt/frigate-recordings
|
|
ls /mnt/frigate-recordings/ # Expect: frigate recording directories
|
|
```
|
|
|
|
**Step 2: Add to fstab using UUID for reliability**
|
|
|
|
```bash
|
|
# Get UUID
|
|
UUID=$(sudo blkid -s UUID -o value /dev/sda1)
|
|
echo "UUID=$UUID /mnt/frigate-recordings ext4 defaults,_netdev 0 2" | sudo tee -a /etc/fstab
|
|
```
|
|
|
|
**Step 3: Verify**
|
|
|
|
```bash
|
|
df -h /mnt/frigate-recordings # Expect: ~4.5T disk
|
|
```
|
|
|
|
---
|
|
|
|
### Task 5: Re-initialize Docker Swarm
|
|
|
|
**Target:** hf-pdocker-01 (192.168.86.192), then hf-pdocker-02 and bart
|
|
|
|
**Step 1: Initialize Swarm on hf-pdocker-01**
|
|
|
|
```bash
|
|
# On hf-pdocker-01:
|
|
docker swarm init --advertise-addr 192.168.86.192
|
|
```
|
|
|
|
Save the worker join token from the output.
|
|
|
|
**Step 2: Clean up stale Swarm state on workers**
|
|
|
|
```bash
|
|
# On hf-pdocker-02 (192.168.86.100):
|
|
docker swarm leave --force
|
|
|
|
# On bart (192.168.86.167):
|
|
docker swarm leave --force
|
|
```
|
|
|
|
**Step 3: Rejoin workers**
|
|
|
|
```bash
|
|
# On hf-pdocker-02:
|
|
docker swarm join --token <WORKER_TOKEN> 192.168.86.192:2377
|
|
|
|
# On bart:
|
|
docker swarm join --token <WORKER_TOKEN> 192.168.86.192:2377
|
|
```
|
|
|
|
**Step 4: Verify cluster**
|
|
|
|
```bash
|
|
# On hf-pdocker-01:
|
|
docker node ls # Expect: 3 nodes, hf-pdocker-01 as Leader/Manager, others as Workers
|
|
```
|
|
|
|
**Step 5: Recreate overlay networks**
|
|
|
|
```bash
|
|
# On hf-pdocker-01:
|
|
docker network create --driver overlay --attachable traefik-public
|
|
```
|
|
|
|
---
|
|
|
|
### Task 6: Deploy Frigate NVR
|
|
|
|
**Target:** hf-pdocker-01 (192.168.86.192)
|
|
|
|
**Step 1: Update Frigate config MQTT address**
|
|
|
|
The Frigate config at `/mnt/docker-data/configs/frigate/config/config.yml` has MQTT pointed at `192.168.86.192:1883` (the old hf-pdocker-01 address). Mosquitto is currently running on bart (192.168.86.167) as a failover service.
|
|
|
|
```bash
|
|
# On hf-pdocker-01, edit the config to point MQTT to bart:
|
|
sed -i 's/host: 192.168.86.192/host: 192.168.86.167/' /mnt/docker-data/configs/frigate/config/config.yml
|
|
```
|
|
|
|
Verify the change:
|
|
```bash
|
|
grep -A2 "^mqtt:" /mnt/docker-data/configs/frigate/config/config.yml
|
|
# Expect: host: 192.168.86.167
|
|
```
|
|
|
|
**Step 2: Deploy Frigate**
|
|
|
|
```bash
|
|
cd /mnt/docker-data/compose/hf-pdocker-01/frigate
|
|
docker compose up -d
|
|
```
|
|
|
|
**Step 3: Verify**
|
|
|
|
```bash
|
|
docker ps --filter name=frigate --format "table {{.Names}}\t{{.Status}}" # Expect: Up
|
|
curl -s http://localhost:5000/api/version # Expect: Frigate version response
|
|
curl -s http://localhost:5000/api/stats | jq '.detectors' # Expect: openvino detector ~10ms inference
|
|
```
|
|
|
|
Wait 1-2 minutes for cameras to initialize, then check:
|
|
```bash
|
|
curl -s http://localhost:5000/api/stats | jq '.cameras | keys' # Expect: list of camera names
|
|
```
|
|
|
|
---
|
|
|
|
### Task 7: Deploy Farm Agent
|
|
|
|
**Target:** hf-pdocker-01 (192.168.86.192)
|
|
|
|
The existing farm-agent compose references `127.0.0.1:5050` (local registry, which is gone). We'll build the image directly from Gitea instead.
|
|
|
|
**Step 1: Clone farm-manager repo and build agent image**
|
|
|
|
```bash
|
|
cd /tmp
|
|
git clone http://192.168.86.100:3003/jeremy/farm-manager.git
|
|
cd farm-manager/agent
|
|
docker build -t farm-agent:latest .
|
|
```
|
|
|
|
**Step 2: Update compose file to use local image**
|
|
|
|
```bash
|
|
# Edit the compose file on NAS
|
|
sed -i 's|image: 127.0.0.1:5050/farm-agent:latest|image: farm-agent:latest|' /mnt/docker-data/compose/hf-pdocker-01/farm-agent/docker-compose.yml
|
|
```
|
|
|
|
**Step 3: Deploy**
|
|
|
|
```bash
|
|
cd /mnt/docker-data/compose/hf-pdocker-01/farm-agent
|
|
docker compose up -d
|
|
```
|
|
|
|
**Step 4: Verify**
|
|
|
|
```bash
|
|
docker ps --filter name=farm-agent --format "table {{.Names}}\t{{.Status}}"
|
|
curl -s http://localhost:8889/health # Expect: healthy response
|
|
```
|
|
|
|
---
|
|
|
|
### Task 8: Deploy Frigate-Notify v2
|
|
|
|
**Target:** hf-pdocker-01 (192.168.86.192)
|
|
|
|
**Step 1: Clone frigate-notify repo**
|
|
|
|
```bash
|
|
cd /tmp
|
|
git clone http://192.168.86.100:3003/jeremy/frigate-notify.git
|
|
```
|
|
|
|
**Step 2: Build the image**
|
|
|
|
```bash
|
|
cd /tmp/frigate-notify
|
|
docker build -t frigate-notify:latest .
|
|
```
|
|
|
|
**Step 3: Create .env file with secrets**
|
|
|
|
The compose file needs `ANTHROPIC_API_KEY`, `MATRIX_ACCESS_TOKEN`, and `MATRIX_ROOM_ID`. Retrieve these from Vaultwarden or use known values.
|
|
|
|
Known values from MEMORY.md:
|
|
- `MATRIX_ACCESS_TOKEN`: `syt_ZnJpZ2F0ZQ_uaKUheedpkQBqtCaldsa_2ifSTC` (bot: @frigate:hobbs.farm)
|
|
- `MATRIX_ROOM_ID`: `!MTsFCQjnmLUNFGJePz:hobbs.farm`
|
|
- `ANTHROPIC_API_KEY`: retrieve from vault or from bart's ai-agents .env
|
|
|
|
```bash
|
|
cat > /mnt/docker-data/compose/hf-pdocker-01/frigate-notify/.env << 'EOF'
|
|
ANTHROPIC_API_KEY=<retrieve from vault>
|
|
MATRIX_ACCESS_TOKEN=syt_ZnJpZ2F0ZQ_uaKUheedpkQBqtCaldsa_2ifSTC
|
|
MATRIX_ROOM_ID=!MTsFCQjnmLUNFGJePz:hobbs.farm
|
|
EOF
|
|
```
|
|
|
|
**Step 4: Update compose to use built image instead of build context, and fix IPs**
|
|
|
|
The compose file on NAS references `build: context: .` which won't work from NAS path. Update to use the locally built image. Also update MQTT and Matrix homeserver IPs since those services are on bart now.
|
|
|
|
Updated compose should have:
|
|
- `image: frigate-notify:latest` (instead of `build:`)
|
|
- `FRIGATE_URL=http://localhost:5000` (Frigate is now local on same host)
|
|
- `MQTT_HOST=192.168.86.167` (Mosquitto on bart)
|
|
- `MATRIX_HOMESERVER=http://192.168.86.167:8008` (Synapse on bart)
|
|
|
|
**Step 5: Deploy**
|
|
|
|
```bash
|
|
cd /mnt/docker-data/compose/hf-pdocker-01/frigate-notify
|
|
docker compose up -d
|
|
```
|
|
|
|
**Step 6: Verify**
|
|
|
|
```bash
|
|
docker ps --filter name=frigate-notify --format "table {{.Names}}\t{{.Status}}"
|
|
curl -s http://localhost:5199/health # Expect: healthy
|
|
```
|
|
|
|
---
|
|
|
|
### Task 9: Restore Cron Jobs
|
|
|
|
**Target:** hf-pdocker-01 (192.168.86.192)
|
|
|
|
**Step 1: Verify scripts are accessible on NAS**
|
|
|
|
```bash
|
|
ls -la /mnt/docker-data/scripts/sync-frigate-to-nas.sh
|
|
ls -la /mnt/docker-data/scripts/cleanup-frigate-media.sh
|
|
cat /mnt/docker-data/scripts/sync-frigate-to-nas.sh
|
|
cat /mnt/docker-data/scripts/cleanup-frigate-media.sh
|
|
```
|
|
|
|
**Step 2: Make scripts executable**
|
|
|
|
```bash
|
|
chmod +x /mnt/docker-data/scripts/sync-frigate-to-nas.sh
|
|
chmod +x /mnt/docker-data/scripts/cleanup-frigate-media.sh
|
|
```
|
|
|
|
**Step 3: Install crontab entries**
|
|
|
|
```bash
|
|
(crontab -l 2>/dev/null; echo "0 2 * * * /mnt/docker-data/scripts/sync-frigate-to-nas.sh") | crontab -
|
|
(crontab -l 2>/dev/null; echo "0 3 * * 0 /mnt/docker-data/scripts/cleanup-frigate-media.sh") | crontab -
|
|
```
|
|
|
|
**Step 4: Verify**
|
|
|
|
```bash
|
|
crontab -l # Expect: both cron entries listed
|
|
```
|
|
|
|
---
|
|
|
|
### Task 10: Monitoring Integration
|
|
|
|
**Target:** hf-pdocker-01 + hf-pdocker-02 (Prometheus)
|
|
|
|
**Step 1: Deploy Swarm global services (Telegraf + Node-exporter)**
|
|
|
|
On hf-pdocker-01, deploy the monitoring stacks that run globally:
|
|
|
|
```bash
|
|
# Check if the stack files exist on NAS
|
|
ls /mnt/docker-data/compose/hf-pdocker-01/ # Look for telegraf, node-exporter stacks
|
|
```
|
|
|
|
If Telegraf and Node-exporter were Swarm stacks, redeploy them:
|
|
```bash
|
|
# These were global swarm services - redeploy the stacks
|
|
docker stack deploy -c /path/to/telegraf-stack.yml telegraf
|
|
docker stack deploy -c /path/to/node-exporter-stack.yml node-exporter
|
|
```
|
|
|
|
**Step 2: Update Prometheus blackbox targets**
|
|
|
|
On hf-pdocker-02 (192.168.86.100), ensure Prometheus has blackbox probe targets for the new services:
|
|
|
|
Targets to verify/add:
|
|
- `http://192.168.86.192:5000` (Frigate)
|
|
- `http://192.168.86.192:5199/health` (Frigate-Notify)
|
|
- `http://192.168.86.192:8889/health` (Farm Agent)
|
|
|
|
**Step 3: Hot-reload Prometheus**
|
|
|
|
```bash
|
|
# On hf-pdocker-02:
|
|
curl -X POST http://localhost:9095/-/reload
|
|
```
|
|
|
|
**Step 4: Verify in Grafana**
|
|
|
|
Check Grafana at http://192.168.86.100:3001 — verify the new targets show as UP in the Prometheus targets page.
|
|
|
|
---
|
|
|
|
## Phase 1 Complete Checklist
|
|
|
|
After all tasks, verify:
|
|
- [ ] Docker running on hf-pdocker-01
|
|
- [ ] NFS mount at /mnt/docker-data working
|
|
- [ ] 5TB disk mounted at /mnt/frigate-recordings
|
|
- [ ] Swarm cluster: 3 nodes (1 manager + 2 workers)
|
|
- [ ] Frigate running, cameras streaming, OpenVINO detector working
|
|
- [ ] Farm Agent responding on :8889
|
|
- [ ] Frigate-Notify v2 healthy on :5199
|
|
- [ ] Cron jobs installed for sync + cleanup
|
|
- [ ] Prometheus monitoring all new endpoints
|
|
- [ ] All blackbox probes green
|
|
|
|
## Phase 2 (Future)
|
|
|
|
Migrate failover services back to hf-pdocker-01:
|
|
- Traefik (from hf-pdocker-02)
|
|
- Monitoring stack (from hf-pdocker-02)
|
|
- AdGuard Home (from hf-pdocker-02)
|
|
- Home Assistant, ESPHome, Mosquitto (from bart)
|
|
- Matrix/Synapse (from bart)
|
|
- Guacamole (from bart)
|
|
- AI Agents (from bart)
|
|
- Farm Manager API (new deploy)
|