Files
app-catalog-felhom.eu/CLAUDE.md
T
admin b3eabfd611 catalog: re-pin wanderer to the current upstream shape, retire plant-it, add the resolvability gate
wanderer: ghcr.io/flomp/wanderer:0.16.0 is a ghost - upstream split the app
into web+db images, moved registry and renamed the org. Restructured to
upstream's own v0.20.0 compose (3 services, new /data/plugins volume, second
public hostname for PocketBase, meilisearch pinned DOWN to upstream's v1.36.0
per the R-42 ruling).

plant-it: retired. The repo name was wrong (plant-it-server) but upstream has
DELETED self-hosting; last server image is 2024-12-10 and it needs MySQL+Redis
the template never had. Moved to retired/ rather than deleted - reversible.

R-41 slice 1: check-image-resolvable.py. Encodes two traps - manifest inspect
exits 0 while printing toomanyrequests, and the inverse, where the first sweep
called 24 of 65 pins dead because Hub throttled it. Ambiguity is INCONCLUSIVE,
never an accusation.
2026-07-21 15:30:15 +02:00

42 lines
2.7 KiB
Markdown

# CLAUDE.md — `app-catalog-felhom.eu`
> Loads when Claude Code touches this repo. Current state: `CONTEXT.md` + `CHANGELOG.md` top.
> Cross-repo orientation: workspace-root `/mnt/5_hdd/felhom.eu/git/CLAUDE.md`.
## What this repo is
The Felhom **app catalog**: one directory per app under `templates/<app>/`, each holding exactly
`docker-compose.yml` + `.felhom.yml` (deploy fields, resources, healthcheck probe, app_info — all
customer-facing text in Hungarian). The felhom-controller git-syncs these to every customer box;
`.felhom.yml` drives the deploy wizard. `templates.json` + `scripts/generate-customer.sh` are LEGACY
(Portainer-era) — new apps don't touch them.
## Deploy contract
**Push to `main` = deploy.** The controller's sync picks changes up within 15 minutes (or trigger via
the dashboard "Sablonok frissítése" button / `POST /api/sync`). Only the two template files sync;
deployed `app.yaml` (customer secrets) is never overwritten. Full deploy details: the
`felhom-build-deploy` skill.
## Conventions
- **See `REUSE.md` before adding or editing an app** — canonical example app (paperless-ngx),
required `.felhom.yml` fields, healthcheck family per image type, memory-limit rules, traps.
- Update `REUSE.md` in the same commit that changes a catalog-wide convention.
- `README.md` is the format spec — update its app tables when adding an app.
- Update `CHANGELOG.md` (newest on top) and overwrite `REPORT.md` with every pushed change.
- No secrets in any committed file; secrets are generated at deploy time via `deploy_fields`
`generate:` specs.
- **Never `:latest` or untagged images in templates** — pin a concrete version tag; an app deployed
anywhere in the fleet is pinned to the digest it is currently running (a pin must never cause a
version jump). Digest pins (`@sha256:`) also count. Gate: `python scripts/check-image-pins.py`
(run after any compose change; exit 1 on any floating/missing tag).
- **A pinned tag can still rot away upstream** — the pin gate is syntactic and cannot see that.
Second gate: `python3 scripts/check-image-resolvable.py` (exit 0 resolve / 1 GONE / 2 inconclusive),
run at the start of every catalog campaign and before any publish train that vouches the catalog.
Needs network + `docker`; unauthenticated Docker Hub throttles a full sweep, so `docker login`
first or expect exit 2. It reports a throttle as INCONCLUSIVE, never as a dead image.
- **Retiring an app**: `git mv templates/<app> retired/<app>` (see `retired/README.md`) — the sync
discovers apps by directory, so this un-offers it while keeping it revivable. Sync never removes a
stack dir it already copied, so retirement freezes the app on existing boxes rather than deleting it.