Files
hobbs-iac/docs/plans/2026-03-05-farm-manager-design.md
jeremy de1d9e1d93 infra: full IaC state after hf-pdocker-01 rebuild (2026-03-08)
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>
2026-03-08 18:51:25 -05:00

5.9 KiB

Farm Manager — Design Document

Date: 2026-03-05 Status: Approved

Overview

A web-based dashboard for managing Docker services across the 3-node homelab cluster. Provides full control (start/stop/restart/logs/pull) with service grouping for bulk operations.

Architecture

Three components:

  1. Dashboard — Static HTML/CSS/JS served by the API server. Dark theme, single page with service cards, group management, and slide-out log viewer.
  2. API Server — Python FastAPI on hf-pdocker-01:8888. Serves frontend, proxies Docker commands to node agents, manages group definitions in JSON.
  3. Node Agent — Python FastAPI on each node:8889. Mounts Docker socket, exposes REST API for container operations. Auto-detects Swarm vs Compose containers.
Browser → Dashboard (hf-pdocker-01:8888)
              ↓
         API Server
          ↙   ↓   ↘
     Agent   Agent   Agent
   (01:8889) (02:8889) (bart:8889)
      ↓        ↓        ↓
   Docker    Docker    Docker
   Socket    Socket    Socket

API Endpoints

API Server (hf-pdocker-01:8888)

Method Path Description
GET /api/nodes List all nodes with health status
GET /api/services All containers across all nodes
POST /api/services/{node}/{container}/start Start container
POST /api/services/{node}/{container}/stop Stop container
POST /api/services/{node}/{container}/restart Restart container
GET /api/services/{node}/{container}/logs?tail=100 Stream logs
POST /api/services/{node}/{container}/pull Pull latest image
GET /api/groups List all groups
POST /api/groups Create group
PUT /api/groups/{id} Edit group
DELETE /api/groups/{id} Delete group
POST /api/groups/{id}/start Start all services in group
POST /api/groups/{id}/stop Stop all services in group
POST /api/groups/{id}/restart Restart all services in group

Node Agent (each node:8889)

Method Path Description
GET /containers List all containers with status
POST /containers/{id}/start Start
POST /containers/{id}/stop Stop
POST /containers/{id}/restart Restart
GET /containers/{id}/logs?tail=100 Get logs
POST /containers/{id}/pull Pull latest image
GET /health Agent health check

Frontend UI

  • Sidebar: Node list with health dots, group list with expand/collapse, "All Services" view, group management button
  • Main area: Grid of service cards (name, status badge, node, image, uptime, action buttons)
  • Log viewer: Slide-out right panel, last 200 lines, auto-scroll
  • Group actions: Toolbar with Start All / Stop All / Restart All, confirmation modal for destructive actions
  • Group editor: Modal with name field and checkbox service list
  • Styling: Dark theme, custom CSS variables, no framework

Data Storage

Groups (/mnt/docker-data/configs/farm-manager/groups.json)

{
  "groups": [
    {
      "id": "ai-agents",
      "name": "AI Agents",
      "services": [
        {"node": "hf-pdocker-01", "container": "ai-agents_margaret"},
        {"node": "hf-pdocker-01", "container": "ai-agents_spirit"},
        {"node": "hf-pdocker-01", "container": "ai-agents_bob"},
        {"node": "hf-pdocker-01", "container": "ai-agents_clippy"}
      ]
    }
  ]
}

Node config (config.json)

{
  "nodes": [
    {"name": "hf-pdocker-01", "host": "192.168.86.192", "agent_port": 8889},
    {"name": "hf-pdocker-02", "host": "192.168.86.100", "agent_port": 8889},
    {"name": "bart", "host": "192.168.86.167", "agent_port": 8889}
  ]
}

Default Groups

Group Services
AI Agents margaret, spirit, bob, clippy
Smart Home homeassistant, esphome, mosquitto
Monitoring grafana, prometheus, alertmanager, influxdb, blackbox-exporter
Media jellyfin, sonarr, radarr, sabnzbd, nzbhydra2, jellyseerr
Matrix synapse, synapse-db, wellknown
Guacamole guacamole, guacd, guacamole-db
Dev Tools gitea, gitea-db, semaphore, semaphore-db, wikijs, wikijs-db
Security vaultwarden, trivy, openvas
Network traefik, adguard, unifi, unifi-db
Frigate frigate, frigate-notify

Deployment

Node Agent (all 3 nodes)

  • Path: /mnt/docker-data/compose/{node}/farm-agent/docker-compose.yml
  • Image: built once, pushed to registry at 127.0.0.1:5050
  • Mounts: /var/run/docker.sock
  • Port: 8889
  • mem_limit: 128M

API Server + Dashboard (hf-pdocker-01)

  • Path: /mnt/docker-data/compose/hf-pdocker-01/farm-manager/docker-compose.yml
  • Port: 8888
  • Config: /mnt/docker-data/configs/farm-manager/
  • mem_limit: 256M

Swarm Handling

Node agent auto-detects Swarm-managed containers and uses docker service API for Swarm services, docker API for Compose containers.

Repo

  • Gitea: jeremy/farm-manager (git.hobbs.farm)
  • Structure:
farm-manager/
├── agent/
│   ├── main.py
│   ├── docker_ops.py
│   ├── requirements.txt
│   └── Dockerfile
├── server/
│   ├── main.py
│   ├── routes/
│   ├── static/
│   │   ├── index.html
│   │   ├── style.css
│   │   └── app.js
│   ├── requirements.txt
│   └── Dockerfile
├── tests/
│   ├── test_agent.py
│   ├── test_server.py
│   └── conftest.py
├── config.json
├── groups.json
└── README.md

Testing

Layer Scope Tool
Unit Agent Docker operations, group CRUD, API proxy logic pytest + pytest-asyncio
Integration API server ↔ mock agent, group persistence pytest + httpx TestClient
Contract Agent response schemas match dashboard expectations pydantic models

Monitoring

  • Prometheus blackbox probes: :8888/health and :8889/health on each node
  • No auth (internal LAN only)