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
This commit is contained in:
2026-07-06 14:01:11 +02:00
parent 13eedb1a83
commit d86e25662f
5 changed files with 78 additions and 45 deletions
+1 -1
View File
@@ -23,7 +23,7 @@ None — this repo is templates/config, not code. See §2/§5.
| Docker healthcheck — DB/Redis sidecars | `templates/paperless-ngx/docker-compose.yml` (~L107, L129) | postgres: `pg_isready -U <user> -d <db>`; mariadb: `healthcheck.sh --connect --innodb_initialized`; redis: `redis-cli ping`. App container gets `depends_on: <db>: condition: service_healthy`. |
| Memory convention | `templates/paperless-ngx/docker-compose.yml` (~L71) + `.felhom.yml resources:` | EVERY service has `deploy.resources.limits.memory` (compose is the enforcement). NO `reservations` anywhere. `.felhom.yml mem_limit` = SUM of all containers' limits (see paperless header comment: 768+256+128=1152M); `mem_request` = expected steady-state usage, display-only. |
| Compose file skeleton | `templates/paperless-ngx/docker-compose.yml` (header) | Header comment (app, domain, DB type, RAM math, Pi), `restart: unless-stopped`, `TZ=Europe/Budapest`, explicit `container_name`, `traefik-public` external network + `<app>-internal` for DBs, Traefik labels with ``Host(`${SUBDOMAIN}.${DOMAIN}`)``, named volumes for DB/config (NVMe), `${HDD_PATH}/appdata/<app>/...` for bulk data, `${USERDATA_PATH}/...` for customer-browsable content. |
| App-email (SMTP shim) opt-in | `templates/vaultwarden/.felhom.yml` (`smtp_mapping:`) + README.md §smtp_mapping | `smtp_mapping` maps shim host/port/security/from to the app's own env names; compose MUST reference the mapped `${VAR:-}` keys with empty defaults. STARTTLS if the app can accept self-signed certs, else `security_value: "NONE"` plaintext (or the :2526 plaintext listener for STARTTLS-insistent clients — see calcom/nextcloud). |
| App-email (SMTP shim) opt-in | `templates/vaultwarden/.felhom.yml` (`smtp_mapping:`) + README.md §smtp_mapping | `smtp_mapping` maps shim host/port/security/from to the app's own env names; compose MUST reference the mapped `${VAR:-}` keys with empty defaults. STARTTLS if the app can accept self-signed certs, else `security_value: "NONE"` plaintext (or the :2526 plaintext listener for STARTTLS-insistent clients — see calcom/nextcloud). TRAP: an image that treats defined-but-EMPTY mail vars as "set" (vaultwarden — campaign F1 2026-07-06) needs its own enable-flag gated `false` in compose and flipped `"true"` via `smtp_mapping.extra`; boot-prove a fresh email-off deploy for every new smtp-mapped app. |
| Probe-container naming | `templates/vaultwarden/docker-compose.yml` (`container_name: vaultwarden`) + `templates/sparkyfitness/` | The controller-side `healthcheck.checks[]` probe dials the container whose **name equals the stack (directory) name exactly**; fallback = the FIRST running prefix-match, which in a multi-container stack can be the DB (verified: `felhom-controller/internal/stacks/healthprobe.go` `findProbeContainer`). So the Traefik-exposed service's `container_name` must be exactly the stack name; sidecars `<app>-db`, `<app>-redis`, …. |
## 3. Dangerous lookalikes — do NOT copy