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
This commit is contained in:
@@ -1,51 +1,26 @@
|
||||
# REPORT — vaultwarden F1 fix: `_ENABLE_SMTP` boot-gate (2026-07-06)
|
||||
# REPORT — healthcheck sweep: `localhost` → `127.0.0.1` across all 48 templates (2026-07-06)
|
||||
|
||||
**Class:** implementation (campaign-finding fix; push = deploy).
|
||||
**Baseline:** `main` @ `13eedb1` → (this commit). Provenance: felhom.eu
|
||||
`documentation/audits/CAMPAIGN-nomercy-2026-07-06.md` finding **F1** (pilot-blocking: every fresh
|
||||
vaultwarden deploy with app-email off — the default — crash-loops).
|
||||
**Class:** implementation (mechanical sweep; push = deploy). **Baseline:** `main` @ `d86e256` → (this commit).
|
||||
Part C of the pilot-blockers bundle (A = agent v0.73.0 F2, B = controller v0.102.0 async restore).
|
||||
Provenance: RERUN vaultwarden healthcheck observation, escalated to a class.
|
||||
|
||||
## Corrected root cause (the campaign report's hypothesis was wrong)
|
||||
## The class
|
||||
48/53 templates used `localhost` in their docker healthcheck `test:` line. BusyBox `wget` (and the
|
||||
node `http.get`, python `urllib`/`socket.create_connection`, and `curl` one-shot forms) resolve
|
||||
`localhost`→IPv6 `::1` with NO cross-address-family fallback, so an app that binds IPv4-only reads
|
||||
docker-`unhealthy` while fully serving (vaultwarden, re-run 2026-07-06).
|
||||
|
||||
Not "shim sets SMTP_FROM without SMTP_HOST" — with app-email off the shim injects **nothing**. The
|
||||
crasher: the template always defines `SMTP_HOST=${SMTP_HOST:-}` and `SMTP_FROM=${SMTP_FROM:-}`;
|
||||
vaultwarden's `get_env_str_value` returns `Some("")` for a defined-empty var (**empty counts as
|
||||
set**), and with `_enable_smtp` defaulting `true` upstream, its validation
|
||||
`smtp_host.is_some() == smtp_from.is_empty()` → `true == true` → config error → exit → crash-loop.
|
||||
The old template comment ("empty SMTP_HOST = mail stays disabled") was wrong for this image.
|
||||
## The change
|
||||
Mechanical `localhost`→`127.0.0.1`, scoped strictly to the healthcheck `test:` lines of the 48 affected
|
||||
`templates/*/docker-compose.yml` (all four check-binary forms incl. mealie's python socket tuple). Diff
|
||||
review confirmed: **no** app env/config/label line changed; `.felhom.yml` files were already clean (zero
|
||||
occurrences). New REUSE.md convention row.
|
||||
|
||||
## Empirical probe (mandatory gate, run on 180 against the pinned image BEFORE editing)
|
||||
## Live acceptance
|
||||
Catalog synced to guest 9201 (`POST /api/sync` 200); vaultwarden template + container now
|
||||
`http://127.0.0.1:80/alive`. **vaultwarden recreated → docker-`healthy`** (the observation's subject flips).
|
||||
bookstack got the same 127.0.0.1 sweep but stays `unhealthy` from an **app-level HTTP 500** on its health
|
||||
path (pre-existing, unrelated to localhost — documented).
|
||||
|
||||
| Probe | Env | Result |
|
||||
|---|---|---|
|
||||
| P1 (pre-fix shape) | `SMTP_HOST=` `SMTP_FROM=` (defined-empty) | **exit 12** — *"Both `SMTP_HOST` and `SMTP_FROM` need to be set for email support without `USE_SENDMAIL`"* (exact campaign error) — the image-level red-proof |
|
||||
| P2 (fix, OFF) | + `_ENABLE_SMTP=false` | **boots** — "Rocket has launched", running |
|
||||
| P3 (fix, ON) | `_ENABLE_SMTP=true` + host + from | **boots** — running (no SMTP connect at boot) |
|
||||
|
||||
(P2/P3 needed `I_REALLY_WANT_VOLATILE_STORAGE=true` to bypass the unrelated no-volume guard in the
|
||||
bare `docker run`; P1 control re-run with it still crashes on the SMTP error, isolating the cause.)
|
||||
Logs: DooPlex `~/campaign-nomercy-2026-07-05/evidence/PROBE-F1/`.
|
||||
|
||||
## Changes
|
||||
|
||||
- `templates/vaultwarden/docker-compose.yml` — `_ENABLE_SMTP=${_ENABLE_SMTP:-false}` added to the
|
||||
SMTP group; the wrong comment replaced with the empty-counts-as-set TRAP note (+ config.json
|
||||
admin-panel precedence note). Nothing else touched.
|
||||
- `templates/vaultwarden/.felhom.yml` — `smtp_mapping.extra: _ENABLE_SMTP: "true"` (rides the
|
||||
existing `smtpEnv` extra loop; zero controller change).
|
||||
- `REUSE.md` — TRAP appended to the App-email row: strict images need the enable-flag pattern;
|
||||
boot-prove fresh email-off deploys for every new smtp-mapped app.
|
||||
- `CHANGELOG.md` — entry incl. the sweep note.
|
||||
|
||||
## Sweep note (documentation only, no edits)
|
||||
|
||||
calcom, gitea, mealie, nextcloud, rallly (and gitea's `GITEA__mailer__SMTP_ADDR=${...:-}`) are
|
||||
**boot-proven tolerant** of defined-empty mail env — all ran healthy as fresh email-off deploys in
|
||||
the campaign. Vaultwarden was the only strict image.
|
||||
|
||||
## Validation
|
||||
|
||||
- Probe gate P1/P2/P3 above (image level).
|
||||
- Live pipeline validation (Scenario A fresh email-off deploy healthy; Scenario B toggle ON→OFF
|
||||
regression) executed as part of the controller v0.101.0 deployment — see
|
||||
felhom-controller/REPORT.md for the live evidence.
|
||||
## Not changed
|
||||
Only healthcheck `test:` lines. No env, config, labels, ports, or `.felhom.yml`.
|
||||
|
||||
Reference in New Issue
Block a user