Files
deploy-felhom-compose/TASK.md
T

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 pull on 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 (&#x1F7E2;), but Go's html/template auto-escapes them to literal text (&amp;#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 "&#x1F7E2;" // green circle
	case "warn":
		return "&#x1F7E1;" // yellow circle
	case "down", "fail":
		return "&#x1F534;" // red circle
	default:
		return "&#x26AA;" // 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:

  1. Dashboard: colored dot (green/yellow/red) before customer name, no &#x text
  2. Customer detail: colored dot in header
  3. 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.eu shows colored dot, not &#x1F7E2; text
  • hub.exe no longer in repo (git ls-files hub/hub.exe returns empty)
  • CLAUDE.md exists in repo root
  • .gitignore exists in repo root