Commit Graph

7 Commits

Author SHA1 Message Date
admin 122bbeea48 papra: mount the volume where the app actually writes (R-156, last leg)
gates / gates (push) Successful in 1s
papra mounted papra_data:/app/data while the application writes to
/app/app-data, so its database sat in the container's writable layer: lost on
redeploy, and tarred nightly as an empty directory while the healthcheck stayed
green. Last of the three apps R-156 convicted.

Decided from the IMAGE, not the README. docker inspect of
ghcr.io/papra-hq/papra:26.6.1-rootless gives WORKDIR=/app and all three data
paths under ./app-data (DATABASE_URL, DOCUMENT_STORAGE_FILESYSTEM_ROOT,
PAPRA_CONFIG_DIR) — and /app/data does not exist in the image at all.

Reconfiguring the app to write to /app/data was available and deliberately not
taken: it enumerates data paths, so a fourth added upstream would escape to the
writable layer again, silently — this defect re-armed. Mounting the app's own
data ROOT captures every current and future path by construction.

Precondition checked rather than inherited: docker ps -a (including stopped) on
BOTH demo guests, plus the hub fleet view (two enrolled hosts, zero papra) —
both boxes were wiped and rebuilt today, so the 2 August evidence was re-measured.

Proven by the runtime gate in both directions: CLEAN with the self-test passing,
and BROKEN when the mount is reverted, with the exact R-156 evidence. Full
catalog_gates.py papra: all three gates OK.
2026-08-03 11:29:51 +02:00
admin acfbd6e527 papra + wishlist: fix lying wget healthchecks (images ship only node)
Both crashes above were masking a second defect: once each app actually stayed
up, it sat permanently unhealthy because its healthcheck called wget, and
neither image has wget or curl -- only node. Traefik does not route to an
unhealthy container, so both would have served 404 to the customer regardless.

Switched both to the Node-exec family (http.get, exit non-zero on 5xx/error).

Campaign 7 catalog sweep.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nn3VgQk9iwEGgyx6QJ2NvE
2026-07-19 02:23:46 +02:00
admin 05cb216968 papra: add required AUTH_SECRET (app refuses to boot without it)
papra was NOT version-bumped by this campaign -- it crash-looped at its existing
26.6.1-rootless pin, so this is a PRE-EXISTING catalog defect: papra has never
been deployable from this template.

  Invalid configuration: In production, the auth secret must not be the default
  one. Please set a secure auth secret using the AUTH_SECRET environment
  variable.

Added as a generated hex:32 secret and marked data_key: true -- it signs
sessions, so regenerating it on restore would invalidate every login.

Campaign 7 catalog sweep.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nn3VgQk9iwEGgyx6QJ2NvE
2026-07-19 00:42:29 +02:00
admin 71828a81cf image pinning: eliminate :latest from all 5 unpinned templates + standing gate
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.
2026-07-12 14:37:57 +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 87d0e5e59d feat: use ${SUBDOMAIN} variable in all templates
All 51 docker-compose.yml: replaced hardcoded subdomain.${DOMAIN}
with ${SUBDOMAIN}.${DOMAIN} in Traefik labels, app env vars, and
comments.

All 51 .felhom.yml: added SUBDOMAIN deploy field (type: subdomain)
with default matching existing subdomain metadata value.

Works with felhom-controller v0.27.0 which validates and stores the
user-chosen subdomain in app.yaml. Existing deployed apps get
SUBDOMAIN auto-injected via InjectMissingFields() on next sync.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 15:06:44 +01:00
admin 0bd3f2a0e2 added apps! 2026-02-15 08:47:15 +01:00