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>
5.9 KiB
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:
- Dashboard — Static HTML/CSS/JS served by the API server. Dark theme, single page with service cards, group management, and slide-out log viewer.
- API Server — Python FastAPI on hf-pdocker-01:8888. Serves frontend, proxies Docker commands to node agents, manages group definitions in JSON.
- 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/healthand:8889/healthon each node - No auth (internal LAN only)