71828a81cf
bentopdf :latest -> v2.8.6; calibre-web :latest -> v4.0.6 (== running digest on demo 9201, c31a738b - pin is a no-op); papra :latest -> 26.6.1-rootless (latest was the rootless variant); recipe-importer :latest -> v0.9.11 (tag pre-existed, digest-equal, no retag needed); termix :latest -> 2.5.0. All five pins digest-identical to what :latest resolved to on 2026-07-12. New gate scripts/check-image-pins.py (catches floating tags AND untagged refs; red-proofed both shapes). Standing rule in CLAUDE.md + REUSE.md row.
34 lines
1.9 KiB
Markdown
34 lines
1.9 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 `e:\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).
|