5.1 KiB
CLAUDE.md — Project Instructions for Claude Code
This file is read automatically by Claude Code at the start of every session. It replaces the "Instructions" panel from the claude.ai Project. Keep it updated as the project evolves.
Project overview
Creating a business (Felhom) for home-server deployment for Hungarian customers. This repository
(deploy-felhom-compose) contains the felhom-controller — a Go application that manages Docker
Compose stacks on customer hardware via a Hungarian-language web dashboard.
See controller/README.md for full architecture and status.
See CONTEXT.md for current project state, recent work, and decisions (update after each session).
Claude in Chrome extension is available — can be used to test web UI on demo-felhom.eu or verify dashboard deployments in browser.
Code quality rules
- Always double-check generated code for bugs, logic issues, syntax errors
- Handle edge cases without overcomplicating the script/program
- Add debug capabilities (logging, verbose output) for easier troubleshooting
- If you need more input or troubleshooting command output, ask first — don't guess
Repository structure
This repo has two main parts:
deploy-felhom-compose/
├── controller/ # Go application (this is the main codebase)
│ ├── cmd/controller/ # Entry point (main.go)
│ ├── internal/
│ │ ├── config/ # YAML config loading
│ │ ├── stacks/ # Docker Compose operations, deploy flow
│ │ ├── api/ # REST API endpoints
│ │ └── web/ # Dashboard UI (embedded HTML/CSS templates)
│ ├── Dockerfile
│ ├── Makefile
│ └── go.mod
├── scripts/ # Setup scripts for customer nodes
├── CLAUDE.md # This file
└── CONTEXT.md # Project memory / state
Related repositories (not in this repo)
- app-catalog-felhom.eu — Docker Compose templates + .felhom.yml metadata per app
- felhom.eu — Website (htmls) + k3s manifests for the web server
- homelab-manifests — Viktor's k3s cluster manifests (dooplex.hu services)
- misc-scripts — Helper scripts for daily tasks
All hosted at gitea.dooplex.hu/admin/
Test environments
| Node | Hardware | Domain | IP | Notes |
|---|---|---|---|---|
| demo-felhom | Acemagic N100, 16G RAM, 512G SSD + 1TB HDD | demo-felhom.eu | 192.168.0.162 | Primary test node, Cloudflare Tunnel |
| pi-customer-1 | Raspberry Pi 3B+, 1G RAM, 32G SD | pi-customer-1.local | 192.168.0.161 | Secondary test, not yet active |
- Pi-hole DNS on local network forwards
*.demo-felhom.eu→ 192.168.0.162 - External access via Cloudflare Tunnel → Traefik reverse proxy
Build & deploy workflow
Code is edited locally on Windows. Build happens on the server via SSH.
# Push changes
git add -A && git commit -m "..." && git push
# Build + push image on server
ssh kisfenyo@192.168.0.180 "cd ~/build/felhom-controller && git -C ~/git/deploy-felhom-compose pull && ./build.sh --push"
# Deploy on demo node
ssh kisfenyo@192.168.0.162 "cd /opt/docker/felhom-controller && docker pull gitea.dooplex.hu/admin/felhom-controller: && docker compose up -d"
Tech stack
- Language: Go 1.22+
- Web framework: stdlib
net/http+html/template(no frameworks) - Templates: Embedded as Go string constants in
templates.go(Hungarian UI) - CSS: Single embedded const in
templates.go(no external CSS files) - Auth: bcrypt password hash + session cookies
- Container orchestration: Docker Compose via CLI (
docker compose up -d) - Reverse proxy: Traefik (separate stack, managed by controller)
- Tunnel: Cloudflare Tunnel (cloudflared, separate stack)
Key patterns
- All UI text is in Hungarian (Budapest timezone, Hungarian locale)
- Templates use Go template functions:
stateColor,stateLabel,stateIcon,stateStr,isOperational,logoURL,logoPNGURL,appPageURL - Container states:
running,starting,unhealthy,stopped,exited,restarting,paused,not_deployed - Docker
.Statefield is combined with.Statusfield to detect health substatus - Stacks are sorted alphabetically by DisplayName
- Protected stacks (traefik, cloudflared, felhom-controller) can't be stopped from UI
app.yamlpersists deploy config;deployed: trueflag controls UI state- Password fields require explicit user input or generation (no silent auto-fill)
Important lessons learned
PAPERLESS_OCR_LANGUAGES(plural, with S) installs tesseract packs;PAPERLESS_OCR_LANGUAGE(singular) selects which to usedocker compose restartdoes NOT pick up new images — always usedocker compose up -d- Go map iteration order is random — always sort before displaying in UI
- Docker's
.Statefield says "running" even for unhealthy containers — must parse.Statusfor health info - After
DeployStack()succeeds, update in-memoryDeployedflag immediately —RefreshStatus()only reads docker ps, not app.yaml