10 KiB
TASK: Create CLAUDE.md + cleanup + statusIcon fix (felhom.eu repo)
Context
The felhom.eu repo lacks a CLAUDE.md with build instructions for the hub, has no .gitignore (so hub.exe got committed), and has a statusIcon rendering bug on the hub dashboard.
Current state: Hub v0.1.2 running on k3s. Controller v0.6.2 on demo node.
All changes in this task are in the felhom.eu repo only.
Task 1: Create CLAUDE.md
Create CLAUDE.md in the repo root (E:\git\felhom.eu\CLAUDE.md) with the following content.
Use the controller's CLAUDE.md (in deploy-felhom-compose) as a style reference.
The CLAUDE.md should include these sections:
Project overview
This repo (felhom.eu) contains:
- Website (
website/) — Static HTML pages at felhom.eu, served via k3s nginx + git-sync sidecar - Hub (
hub/) — Go application (felhom-hub) — centralized dashboard for monitoring customer controllers, runs on k3s at hub.felhom.eu - K8s manifests (
manifests/) — k3s deployment manifests for all felhom-system services
See README.md for full architecture, DNS, email, and SEO documentation.
See TASK.md for the current task to implement (if it exists).
Code quality rules
Same as controller CLAUDE.md:
- Always double-check generated code for bugs, logic issues, syntax errors
- Handle edge cases without overcomplicating
- Add debug capabilities for troubleshooting
- Ask for more input rather than guessing
Workspace layout
E:\git\felhom.eu\ (or /e/git/felhom.eu/ in Git Bash)
├── hub/ # felhom-hub Go application
│ ├── cmd/hub/ # Entry point (main.go)
│ ├── internal/
│ │ ├── api/ # Report ingestion API
│ │ ├── store/ # SQLite storage + queries
│ │ └── web/ # Dashboard UI
│ │ ├── server.go # Server, routing, template funcs
│ │ ├── embed.go # go:embed for templates
│ │ └── templates/ # HTML templates + CSS
│ ├── configs/ # Example config files
│ ├── Dockerfile
│ ├── Makefile
│ └── go.mod
├── manifests/ # k3s deployment manifests
│ ├── hub.yaml # Hub deployment (hub.felhom.eu)
│ ├── webpage.yaml # Website + FileBrowser + git-sync
│ ├── contact-mailer.yaml # Contact form email sender
│ ├── healthchecks.yaml # Healthchecks (status.felhom.eu)
│ └── umami.yaml # Analytics (stats.felhom.eu)
├── website/ # Static HTML pages (felhom.eu)
│ ├── index.html
│ ├── alkalmazasok.html
│ ├── ... (all Hungarian, UTF-8 with BOM)
│ └── assets/ # Logos, screenshots, OG images
├── CLAUDE.md # This file
├── README.md # Full project documentation
└── TASK.md # Current task (if exists)
Related repos (same parent directory):
E:\git\deploy-felhom-compose\ # felhom-controller Go app + deploy scripts
E:\git\app-catalog-felhom.eu\ # Docker Compose templates per app
E:\git\homelab-manifests\ # k3s cluster manifests (dooplex.hu services)
E:\git\misc-scripts\ # Helper scripts (build scripts, repo collector)
All repos hosted at gitea.dooplex.hu/admin/.
SSH access
SSH key-based authentication configured. No password prompts.
| Host | IP | User | Role |
|---|---|---|---|
| Build server (k3s node) | 192.168.0.180 | kisfenyo | Build + push images, kubectl |
| Demo node | 192.168.0.162 | kisfenyo | Test deployment (demo-felhom.eu) |
Note: kubectl on the build server requires sudo (k3s kubeconfig permissions).
Build & deploy workflow — Hub
After making code changes to hub/, you MUST build, push, and deploy the new image.
Do NOT leave code changes uncommitted or undeployed.
Step 1: Commit and push changes
cd /e/git/felhom.eu
git add -A && git commit -m "<descriptive message>" && git push
Step 2: Build + push the container image on the build server
The build server (192.168.0.180) has the build toolchain. The build script lives at
~/build/felhom-hub/build.sh on the build server (NOT in this repo).
First, check the current running version:
ssh kisfenyo@192.168.0.180 "sudo kubectl get deploy -n felhom-system hub -o jsonpath='{.spec.template.spec.containers[0].image}'"
Then build with the next version (e.g., if current is 0.1.2, use 0.1.3):
ssh kisfenyo@192.168.0.180 "cd ~/build/felhom-hub && ./build.sh <NEW_VERSION> --push"
The build script:
- Pulls latest code from Gitea (
git pullon the felhom.eu repo) - Copies
hub/source to a clean build workspace - Builds Docker image with version + build-time ldflags
- Pushes to
gitea.dooplex.hu/admin/felhom-hub:<VERSION>and:latest
Step 3: Deploy to k3s
ssh kisfenyo@192.168.0.180 "sudo kubectl set image -n felhom-system deploy/hub hub=gitea.dooplex.hu/admin/felhom-hub:<NEW_VERSION>"
Step 4: Verify the deployment
ssh kisfenyo@192.168.0.180 "sudo kubectl get pods -n felhom-system -l app=hub && echo '---' && sudo kubectl logs -n felhom-system -l app=hub --tail 10"
Should show pod Running and [INFO] felhom-hub <VERSION> starting in logs.
Build workflow summary
| Step | Command | Where |
|---|---|---|
| 1. Commit + push | git add -A && git commit && git push |
Local (this repo) |
| 2. Build + push image | ssh 192.168.0.180 "cd ~/build/felhom-hub && ./build.sh <VER> --push" |
Build server |
| 3. Deploy | ssh 192.168.0.180 "sudo kubectl set image -n felhom-system deploy/hub hub=...:<VER>" |
Build server (kubectl) |
| 4. Verify | ssh 192.168.0.180 "sudo kubectl get pods -n felhom-system -l app=hub" |
Build server |
Build & deploy workflow — Website
The website auto-deploys via git-sync sidecar. Just push to main:
cd /e/git/felhom.eu
git add -A && git commit -m "<message>" && git push
Changes are live within 1-2 minutes. No build step needed.
For emergency edits, use FileBrowser at https://files.felhom.eu.
Build & deploy workflow — K8s Manifests
Manifests are applied manually:
ssh kisfenyo@192.168.0.180 "sudo kubectl apply -f /home/kisfenyo/git/felhom.eu/manifests/<manifest>.yaml"
Remember to git pull on the build server first if you pushed changes locally.
Tech stack (Hub)
- Language: Go 1.24+
- Web framework: stdlib
net/http+html/template - Database: SQLite via
modernc.org/sqlite(pure Go, no CGo) - Auth: bcrypt password hash + basic auth
- Deployment: Docker container on k3s (felhom-system namespace)
- Storage: Longhorn PVC at
/data/(SQLite DB) - Config: YAML file mounted via k8s ConfigMap at
/etc/felhom-hub/hub.yaml
Key patterns
- Hub receives reports from customer controllers via
POST /api/v1/report(Bearer token auth) - Dashboard shows all customers in a table with status, CPU, memory, disk, containers, backup age
- Customer detail page shows system info, report history, full JSON report
- Status logic: OK (report < 30m), WARN (30m-1h or health=warn), DOWN (> 1h or health=fail)
- SQLite timestamps may vary in format — use
parseSQLiteTime()for robust parsing - Auto-refresh: dashboard and detail pages refresh every 60 seconds via
<meta http-equiv="refresh"> - Geo-restricted to Hungary via nginx ingress annotation
File encoding
All HTML files in website/ are UTF-8 with BOM. Ensure your editor preserves this.
Hub Go source files are standard UTF-8 (no BOM).
Task 2: Create .gitignore
Create .gitignore in the repo root with appropriate entries:
# Go binaries
hub/hub
hub/hub.exe
hub/bin/
# Build artifacts
*.exe
*.dll
*.so
*.dylib
# Test and coverage
*.test
*.out
coverage.html
# IDE
.idea/
.vscode/
*.swp
*.swo
*~
# OS
.DS_Store
Thumbs.db
# Temporary files
*.tmp
*.bak
Task 3: Remove hub.exe from git history
After creating .gitignore, remove the committed binary:
git rm --cached hub/hub.exe
This removes it from tracking but the .gitignore prevents re-adding. No need to rewrite
history — just remove from current tree.
Also check for any other binaries that shouldn't be tracked:
find hub/ -name "*.exe" -o -name "hub" -type f -executable
Task 4: Fix hub statusIcon rendering
File: hub/internal/web/server.go
Problem: statusIcon() returns HTML entities (🟢), but Go's html/template
auto-escapes them to literal text (&#x1F7E2;). Additionally, emoji don't respond to
CSS color — but the templates already apply style="color: {{statusColor .OverallStatus}}".
Fix: Change statusIcon() to return ● (U+25CF, BLACK CIRCLE) — a plain Unicode character
that responds to CSS color styling. The existing statusColor() function handles color differentiation.
// BEFORE (broken):
func statusIcon(status string) string {
switch status {
case "ok":
return "🟢" // green circle
case "warn":
return "🟡" // yellow circle
case "down", "fail":
return "🔴" // red circle
default:
return "⚪" // white circle
}
}
// AFTER (works with CSS color):
func statusIcon(status string) string {
return "●"
}
No template changes needed — statusColor() already provides the correct color per status.
Verification:
- Dashboard: colored dot (green/yellow/red) before customer name, no
&#xtext - Customer detail: colored dot in header
- Colors match status (green=OK, yellow=WARN, red=DOWN)
Build & Deploy
After all changes, commit and deploy hub v0.1.3:
# 1. Commit
cd /e/git/felhom.eu
git add -A && git commit -m "add CLAUDE.md, .gitignore, fix statusIcon rendering" && git push
# 2. Build
ssh kisfenyo@192.168.0.180 "cd ~/build/felhom-hub && ./build.sh 0.1.3 --push"
# 3. Deploy
ssh kisfenyo@192.168.0.180 "sudo kubectl set image -n felhom-system deploy/hub hub=gitea.dooplex.hu/admin/felhom-hub:0.1.3"
# 4. Verify
ssh kisfenyo@192.168.0.180 "sudo kubectl rollout status -n felhom-system deploy/hub && sudo kubectl logs -n felhom-system -l app=hub --tail 5"
Post-deploy checklist
hub.felhom.eushows colored●dot, not🟢texthub.exeno longer in repo (git ls-files hub/hub.exereturns empty)CLAUDE.mdexists in repo root.gitignoreexists in repo root