Commit Graph

109 Commits

Author SHA1 Message Date
admin 2ebe082a2a docs: healthcheck sweep REPORT (localhost -> 127.0.0.1, 48 templates, live-validated)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-06 20:43:13 +02:00
admin 8ddd3c9da5 fix(healthcheck): sweep localhost -> 127.0.0.1 across all 48 templates
BusyBox wget (+ node/python/curl one-shots, incl mealie's socket tuple) resolve
localhost -> IPv6 ::1 with no cross-family fallback; an IPv4-only-binding app
reads docker-unhealthy while serving (vaultwarden, re-run 2026-07-06). Escalates
that instance to the class. Scoped strictly to healthcheck test: lines
(diff-reviewed: no env/config/label changed; .felhom.yml already clean). New
REUSE.md convention row.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-06 20:25:54 +02:00
admin d86e25662f fix(vaultwarden): _ENABLE_SMTP boot-gate — fresh email-off deploys crash-looped (campaign F1)
Vaultwarden treats defined-but-empty SMTP_HOST/SMTP_FROM as "set"; with upstream
_enable_smtp defaulting true its validation errors out and the container
crash-loops on every fresh deploy with app-email off (the default). Gate the
SMTP group with _ENABLE_SMTP: compose default false (clean boot, mail off),
flipped "true" by the app-email injection via smtp_mapping.extra. Proven on the
pinned 1.33.2-alpine image (P1 repro exit 12 / P2 off boots / P3 on boots).
REUSE.md: strict-image TRAP row. Sweep note: the other 5 smtp-mapped templates
are campaign-boot-proven tolerant; no edits.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-06 14:01:11 +02:00
admin 13eedb1a83 docs: CHANGELOG + REPORT — sparkyfitness finalization + validation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-03 19:48:31 +02:00
admin c7490f7a40 sparkyfitness: finalize — image-inspected healthchecks + probe-container naming (REUSE row added)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-03 19:40:09 +02:00
admin 15cdf7b090 docs: CLAUDE.md light expansion (repo purpose, deploy contract, pointers)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-03 11:26:12 +02:00
admin c5a3d1b15b docs: REUSE.md introduced — catalog conventions map (canonical app, healthcheck families, traps) + minimal CLAUDE.md
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
2026-07-03 09:39:38 +02:00
admin bb81cd414a app-email: calcom+nextcloud wired & send-tested; calcom healthcheck GET fix + docs
calcom + nextcloud both send live via the :2526 plaintext listener (calcom signup =
Nodemailer; nextcloud password-reset = Symfony Mailer), both From <app>@felhom.eu.
calcom healthcheck: wget GET not --spider (HEAD 405s). CHANGELOG + REPORT.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 13:56:49 +02:00
admin e90dae890e calcom: fix healthcheck path (/api/health 404 in v4.x -> /api/auth/providers)
/api/health doesn't exist in cal.com v4.x (404) -> container stayed unhealthy ->
Traefik wouldn't route it. /api/auth/providers is a stable 200 once serving.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 13:47:18 +02:00
admin 342a389f3d calcom: add DATABASE_DIRECT_URL (required by Prisma; migrations failed without it)
Cal.com's prisma schema declares directUrl=env(DATABASE_DIRECT_URL); without it the
startup 'prisma migrate deploy' fails (P1012) and the schema stays incomplete -> the app
500s. Set to the same direct Postgres URL. Pre-existing, never caught (bad image pin
meant calcom never deployed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 13:42:15 +02:00
admin 9dd4923053 calcom: fix non-existent image pin v4.8.7 -> v4.6.9 (nearest valid 4.x)
calcom/cal.com:v4.8.7 is a git tag with no published Docker image; the manifest is
unknown. v4.6.9 is the nearest valid 4.x image (same EMAIL_SERVER_* env behavior).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 13:33:04 +02:00
admin 1b89692a49 app-email: calcom + nextcloud mappings (tls_mode=plaintext, nextcloud split-From)
calcom (Nodemailer) + nextcloud (Symfony) opportunistically STARTTLS with no cert-skip
-> tls_mode=plaintext (:2526, no STARTTLS advertised). nextcloud splits From via
from_domain_var (MAIL_FROM_ADDRESS + MAIL_DOMAIN). Compose files reference injected env.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 13:14:01 +02:00
admin 42bf76f540 docs: REPORT + CHANGELOG — gitea/rallly send-tested live; findings + template fixes
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 11:06:57 +02:00
admin 32c730f749 rallly: fix healthcheck (image has no wget → node http check)
The wget healthcheck always failed (exit 127, no wget in image) → container
unhealthy → Traefik refused to route it. Pre-existing, never caught because the
3.12.1 image pin didn't exist.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 10:54:49 +02:00
admin 47f23bf1e3 rallly: add required SUPPORT_EMAIL + valid NOREPLY_EMAIL default (boots without email)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 10:39:47 +02:00
admin 3b5d102d21 app-email rollout: gitea + rallly mappings; calcom/nextcloud/immich = findings
gitea (STARTTLS + FORCE_TRUST_SERVER_CERT) and rallly (Nodemailer STARTTLS +
SMTP_REJECT_UNAUTHORIZED=false) wired. Fixed rallly's non-existent 3.12.1 pin → 3.11.2.
calcom/nextcloud/immich don't fit the mechanism (self-signed opportunistic-STARTTLS,
split From, no-SMTP-env) — see FINDING doc in felhom.eu.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 10:32:55 +02:00
admin f0529bc9a0 docs: REPORT — note live relay validation
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 08:58:07 +02:00
admin 4581a92781 app-email: smtp_mapping for vaultwarden + mealie
Vaultwarden via STARTTLS (accepts self-signed shim cert); Mealie via plaintext
(NONE) — no accept-invalid-cert option, spike-validated mode. Compose files
reference injected ${SMTP_*}. README documents the pattern.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 08:45:23 +02:00
admin 5d42ca18bf docs: SparkyFitness (v0.17.2) — CHANGELOG + README rows + REPORT
Live-validated on guest 9201 / controller v0.87.0: synced, deployed via the
real dashboard flow, all 3 containers healthy, /api/health UP through the public
edge. Records §1.3 image-probe findings and the deferred interactive-login item.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 15:06:50 +02:00
admin 4351d08daf Add SparkyFitness (v0.17.2) — nutrition/workout tracker
frontend (nginx SPA :80, sole Traefik ingress) + server (Node :3010) +
dedicated postgres:15-alpine. Native email auth (no OIDC), subdomain 'sparky'.
Two DB roles (sparky superuser + sparkyapp limited, auto-created first boot),
PGDATA subdir, data_key on API_ENCRYPTION_KEY + BETTER_AUTH_SECRET.
Transcribed from the validated k3s manifest (homelab-manifests/workout-system).

New files:
  templates/sparkyfitness/docker-compose.yml
  templates/sparkyfitness/.felhom.yml

Image probes (build server, v0.17.2): server node-exec /api/health probe (node
present); frontend wget --spider probe (wget+curl both present).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 14:57:56 +02:00
admin d7a6a17504 docs: correct crafty 4.10.7 report — the 401 was operator-configured MFA, not an upgrade bug (no regression); real MC server on 25565 verified from LAN 2026-06-26 11:57:31 +02:00
admin 0012d66fc3 docs: CHANGELOG + REPORT for crafty 4.10.7 bump, port range, guidance; flag in-place-upgrade TOTP lockout 2026-06-26 11:48:53 +02:00
admin 2d5b835636 crafty-controller: bump image 4.4.8->4.10.7 (security CVEs + Java); publish Java port range 25565-25575; app-page port/connection guidance 2026-06-26 11:37:09 +02:00
admin 886f596393 docs: REPORT for crafty seeded admin password (gokapi pattern); live-verified fresh install + API login 2026-06-26 11:29:04 +02:00
admin 5a403d1003 crafty-controller: seed felhom-generated admin password (gokapi pattern) instead of Crafty's random one; app-page card reads default.json 2026-06-26 11:22:26 +02:00
admin 8fd9c007af crafty-controller: initial_credentials block — surface auto-generated admin password on app page 2026-06-26 11:00:08 +02:00
admin 1216a8a78a crafty-controller: Traefik https backend scheme + scoped skip-verify transport (fixes 502 to TLS backend) 2026-06-26 10:28:59 +02:00
admin 9abd392247 crafty-controller: changelog + report for healthcheck fix (route un-withheld; 502 backend-scheme tracked separately) 2026-06-26 09:56:52 +02:00
admin 68ce009f19 crafty-controller: python3 TLS healthcheck (image has no curl); controller-side probe http->tcp (8443 is TLS) 2026-06-26 09:45:17 +02:00
admin 6a71c5aa0a catalog: add open_path for apps whose UI isn't at / (gokapi=/admin, ghost=/ghost/)
New .felhom.yml field consumed by the controller's Megnyitás link. Audit of all 53 templates: only
gokapi (file-share index redirects away) and ghost (bare / is the public blog; admin at /ghost/) need it;
the rest serve/redirect usefully at root. onlyoffice is API-only (status page at /) — left at root.
2026-06-23 12:00:30 +02:00
admin 6e91a5cbe5 docs: gokapi RedirectUrl + default_creds follow-ups 2026-06-23 11:49:07 +02:00
admin 9db1259750 gokapi: point index RedirectUrl at the app's own /admin (not Gokapi's GitHub)
Gokapi's bare root '/' redirects to RedirectUrl. It was the upstream default (github.com/Forceu/Gokapi),
so the controller's 'Megnyitás' link (always the bare subdomain root) landed on Gokapi's GitHub instead
of the app. Point it at https://${SUBDOMAIN}.${DOMAIN}/admin so the root + the controller link reach
the Gokapi login/panel.
2026-06-23 11:47:14 +02:00
admin ed10e5bb06 gokapi: show admin username (default_creds) + fix first_steps for headless setup
App now auto-configures (no setup wizard), so first_steps described a flow that no longer happens.
Add default_creds 'Felhasználó: admin · jelszó a Beállítások oldalon' so the app-info page shows the
initial admin user like other apps; password stays on the Beállítások page (generated field).
2026-06-23 11:23:41 +02:00
admin 72d8c8b97c docs: gokapi headless-setup fix (CHANGELOG + REPORT) 2026-06-23 11:13:35 +02:00
admin 3ec67ef2f5 gokapi: reproducible headless setup via seed config + --deployment-password
Gokapi v1.9.6 has no env-var setup and otherwise exposes a public /setup (admin-takeover risk).
Entrypoint seeds config.json on first boot (admin, this app's URL, local storage, no-encryption so
it restarts without a prompt) with password/salts cleared, then runs the documented
--deployment-password one-shot to set the felhom-generated admin password before serving — claims
admin at first boot, never exposes /setup. Seed pinned to v1.9.6 (ConfigVersion 21).
2026-06-23 11:07:50 +02:00
admin 690c8dd0b8 Revert gokapi headless-env change: Gokapi (v1.9.6/v2.0.1) has no GOKAPI_USERNAME/PASSWORD env
Verified against Gokapi docs + the v1.9.6 binary: no env-var headless admin setup exists in any
version. Non-interactive setup requires a pre-seeded config.json + --deployment-password. Reverting
the non-functional env so the template isn't misleading; choosing a real fix path with the user.
2026-06-23 08:40:11 +02:00
admin 01936716d3 gokapi: headless first-run setup (GOKAPI_USERNAME=admin + generated GOKAPI_PASSWORD)
Gokapi sat in maintenance mode since deploy because /setup was never completed and the
template provided no headless-setup env. GOKAPI_USERNAME/PASSWORD configure it on first
start; password is felhom-generated (deploy field, shown to customer). Fixes share.* maintenance page.
2026-06-23 08:26:15 +02:00
admin d334dd7007 docs: REPORT covers both catalog HC fixes (komga + gitea)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 16:14:34 +02:00
admin 1a44c1403f docs: CHANGELOG entry for gitea HC fix
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 15:18:10 +02:00
admin 17e00b788e gitea: fix healthcheck — probe /api/healthz (was 404 on /api/v1/version pre-install)
Surfaced during the unattended deploy sweep: a fresh gitea reported unhealthy because
the HC hit /api/v1/version (404 until install-lock); /api/healthz returns 200 while
serving. Fixed both the docker HC and the controller .felhom.yml probe; bumped
start_period to 90s for first-boot DB migration. Same class as the komga fix.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 15:17:52 +02:00
admin f51f794cf0 docs: REPORT for komga healthcheck fix
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 15:12:19 +02:00
admin 9b066de331 komga: fix controller-side health probe path too (/actuator/health)
The .felhom.yml controller probe also pointed at the auth-gated /api/v1/actuator/health
(401) — that is what drives the dashboard 'Nem egészséges' state. Repoint to the
unauthenticated /actuator/health, matching the docker HC fix.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 15:04:52 +02:00
admin 3faa5ae193 komga: fix healthcheck — probe unauthenticated /actuator/health (was 401 on /api/v1/...)
The /api/v1 prefix is auth-gated → old HC got 401 → curl -f failed → container
reported unhealthy while serving fine. Diagnosed live on guest 9201.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 15:03:37 +02:00
admin 939864f2a6 catalog: repoint HDD_PATH defaults/placeholders to /mnt/felhom-drives/<name>
Intermediary-mount re-architecture: drives are visible in-guest at the stable
/mnt/felhom-drives/<name>. Composes already use ${HDD_PATH}/${USERDATA_PATH}
(injected + repointed by controller v0.67.0); this updates the UI placeholders,
templates.json defaults, and doc/script examples to the new convention.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 16:48:52 +02:00
admin f7458487fb docs: REPORT for paperless OCR lang-pack fix
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 08:29:03 +02:00
admin 67037cc064 paperless: fix OCR lang-pack install (space-separated PAPERLESS_OCR_LANGUAGES)
The compose fed the +-joined PAPERLESS_OCR_LANGUAGE (e.g. hun+eng) into
PAPERLESS_OCR_LANGUAGES (the install list), so the image tried to apt-install a bogus
'tesseract-ocr-hun+eng' → hun pack missing → Django check crash-loop on the default
hun+eng. PAPERLESS_OCR_LANGUAGES must be space-separated; set a fixed superset
'eng hun deu' (verified each installs). Found live deploying paperless on guest 9201.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 08:23:21 +02:00
admin 3c13d3e8e9 docs: REPORT for userdata layout repoint
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 22:32:03 +02:00
admin c99070c105 komga + audiobookshelf: add no-new-privileges (root-fallback hardening)
Address security review: reverting to root removed the user:1000 boundary, so add
security_opt no-new-privileges:true to block SUID-based escalation. Full cap_drop
is intentionally NOT applied — the images' root-init needs CHOWN/SETUID/SETGID to
set up /config and /metadata (dropping them reproduces the crash we hit at user:1000).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 22:17:32 +02:00
admin 0d60a5cb2e komga + audiobookshelf: revert to root (user:1000 fallback)
Live try-then-fallback: pinning user 1000:1000 crash-loops both — their named
config/metadata volumes are Docker-created root-owned and the pinned process can't
write them (komga: SQLite /config open fails; audiobookshelf: EACCES mkdir
/metadata/logs; neither has a PUID-style root-init chown). Reverted to root; they
rely on the setgid 2775 userdata dirs (files land group 1000 → FileBrowser browses/reads).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 22:13:29 +02:00
admin 69611cec18 userdata layout: repoint customer-content mounts to ${USERDATA_PATH}
Move every shared-media + ingest mount off ${HDD_PATH}/media onto the new
${USERDATA_PATH}/... convention (controller injects USERDATA_PATH = <namespace>/userdata):
- jellyfin/emby/plex: media:/media:ro ; navidrome: media/music:ro
- audiobookshelf (user 1000:1000): media/{audiobooks,podcasts}
- komga (user 1000:1000): media/comics
- calibre-web (UMASK=002): library->media/books, ingest->import/calibre
- radarr/sonarr (UMASK=002): media/{movies,tv} + downloads (sibling, same FS)
- romm: ROM library -> userdata/roms (browsable); resources stay in appdata
- immich: + external library media/photos:/external/photos:ro (registration is a
  post-deploy admin step — flagged in compose + .felhom.yml)
- paperless: consume -> import/paperless (USERMAP 1000)
- nextcloud: unchanged (fully app-managed)
.felhom.yml first_steps updated for the new browsable drop-zones.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 21:46:23 +02:00