templates: three health probes dial where the app listens (R-618)
gates / gates (push) Successful in 1s

tandoor 8080->80, wger 80->8000, zipline /api/health->/api/healthcheck.

The probe dials <container-name>:<port><path> from inside the compose network, so the port is the
one the process LISTENS on. Each fix matches the port/path that the SAME service's own compose
healthcheck already dials on 127.0.0.1 — the oracle that was sitting in the file all along.

This is P1 and not cosmetic: the guarded update's `verifying` phase waits on this probe, so
`failAndHold` stopped a working app at the end of a SUCCESSFUL update. Measured on 9202 2026-09-21.

No image: line moved, so no catalog_since moves.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-09-22 10:50:01 +02:00
parent d4392e2a10
commit 793c4fba00
4 changed files with 37 additions and 3 deletions
+26
View File
@@ -1,3 +1,29 @@
## Three health probes now dial where the app actually listens (2026-09-22, R-618)
**Templates only, and no `image:` line moved — so no `catalog_since` moves either.**
`.felhom.yml`'s `healthcheck.checks` tells the controller where to knock, and it knocks from INSIDE
the compose network: `<container-name>:<port><path>`. The port is therefore the port the process
listens on inside its container — never the published port and never Traefik's. Three templates
named something else:
| app | was | is | what the app's own compose healthcheck dials |
|---|---|---|---|
| tandoor | port `8080` | port `80` | `http://127.0.0.1:80/accounts/login/` |
| zipline | path `/api/health` | path `/api/healthcheck` | `http://127.0.0.1:3000/api/healthcheck` |
| wger | port `80` | port `8000` | `http://127.0.0.1:8000` |
**Why this is not merely a wrong badge.** The guarded update's `verifying` phase waits on this same
probe, and `failAndHold` runs `compose down` when it never goes green. So a SUCCESSFUL update ended
by STOPPING a working app. Measured on guest 9202, 2026-09-21: tandoor served HTTP 200 on the new
version at four samples across five minutes, docker's own healthcheck green throughout, and the
controller stopped it at +361.9 s.
Proven live on guest 9202 before and after, through the product: at the live pin all three read
`Nem egeszseges` / `Not healthy` on their own app page while their front doors served a real page
(tandoor 200 `Login / Sign In`, zipline 200 `Zipline`, wger 200 `wger Workout Manager`) and docker
reported every container healthy.
## Vikunja fixture: the create verb is PUT, not POST (2026-09-21, R-462)
Test code only, and a one-line correction to the fixture shipped earlier the same night.
+4 -1
View File
@@ -71,7 +71,10 @@ app_info:
healthcheck:
checks:
- type: http
port: 8080
# 80, not 8080: the probe dials the container from INSIDE the compose
# network, so this is the port the process LISTENS on. tandoor's own compose healthcheck
# dials 127.0.0.1:80 (R-618).
port: 80
path: "/accounts/login/"
# --- English copy (localisation slice 5, R-560) --------------------------------------------
+3 -1
View File
@@ -66,7 +66,9 @@ app_info:
healthcheck:
checks:
- type: http
port: 80
# 8000, not 80: gunicorn listens on 8000 inside the container; 80 is only
# what traefik publishes. wger's own compose healthcheck dials 127.0.0.1:8000 (R-618).
port: 8000
# --- English copy (localisation slice 5, R-560) --------------------------------------------
# The Hungarian above is UNCHANGED. A box on English reads this block field by field; a missing
+4 -1
View File
@@ -75,7 +75,10 @@ healthcheck:
checks:
- type: api
port: 3000
path: "/api/health"
# /api/healthcheck, not /api/health: this probe is `api` WITH an expect
# block, so a 404 on the wrong path reads as unhealthy. zipline's own compose healthcheck
# dials /api/healthcheck (R-618).
path: "/api/healthcheck"
expect:
status: 200