With the DATABASE_URL fix zipline started cleanly ('server started
hostname=0.0.0.0 port=3000') but stayed unhealthy. Probing the running container
from inside:
/api/health -> 404
/api/healthcheck -> 200
v4 renamed the endpoint; the template still probed the v3 path.
Campaign 7 catalog sweep.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nn3VgQk9iwEGgyx6QJ2NvE
zipline crash-looped 15 times on a fresh deploy:
ERROR config::readDbVars] No database environment variables found
(DATABASE_URL or all of [DATABASE_USERNAME, DATABASE_PASSWORD,
DATABASE_HOST, DATABASE_PORT, DATABASE_NAME]), exiting...
In Zipline v4 the database variable is DATABASE_URL with NO prefix, while
CORE_SECRET kept its prefix (confirmed against the upstream config docs) -- so
only the DB variable was renamed here.
The template was already pinned to the v4 line (4.0.0) before this campaign, and
v4 has always required DATABASE_URL, so zipline has been undeployable from the
catalog for the whole v4 series. PRE-EXISTING defect, surfaced by the sweep.
Campaign 7 catalog sweep.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nn3VgQk9iwEGgyx6QJ2NvE
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
Each app template now declares a healthcheck: section in .felhom.yml
with appropriate probe type (http, api, or tcp) and endpoint based on
the app's known health endpoints. The controller uses these to verify
services are actually responding, not just that containers are running.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>