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
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>
/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>
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>
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>
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>