fix(infra): portable health poll instead of compose --wait (refs #30)
All checks were successful
CI / lint (pull_request) Successful in 48s
CI / build (pull_request) Successful in 42s
CI / unit (pull_request) Successful in 44s
CI / compose-smoke (pull_request) Successful in 3m56s

`make smoke` errored locally because podman-compose doesn't implement
`docker compose up --wait` (`unrecognized arguments: --wait`).

Replace the `--wait` step with infra/wait-healthy.sh, which polls each durable
health-checked service ($(WAIT_SVCS)) via `docker ps` + `docker inspect
'{{.State.Health.Status}}'`. This:

- works on both docker compose (CI) and podman-compose (local) — only plain
  docker primitives, no `--wait`;
- reads the in-container healthcheck, so it needs no host port access (the CI
  runner can't reach published ports);
- ignores the one-shot init jobs, sidestepping the "--wait fails when a
  consumer-less one-shot exits 0" issue (flowable-init).

Verified on podman-compose: wait-healthy.sh reports bff healthy (rc=0); podman
exposes .State.Health.Status (starting -> healthy) and the name filter matches
both `_` and `-` container naming.

Docs: gitea-actions-gotchas.md updated (the two `--wait` sections folded into one
"portable health poll" section).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-25 10:57:52 +02:00
parent b349dff496
commit dda4c58e1c
3 changed files with 63 additions and 38 deletions

View File

@@ -7,10 +7,9 @@
SLN := register-referentie.slnx
COMPOSE := infra/docker-compose.yml
# Long-running services with a healthcheck — the smoke waits on these. One-shot
# init jobs (oz-init, nrc-init, flowable-init) are NOT listed: `--wait` fails when
# a one-shot with no `service_completed_successfully` dependant exits (flowable-init),
# so we wait on the durable services instead. See docs/runbooks/gitea-actions-gotchas.md.
# Long-running services with a healthcheck — the smoke polls these for readiness
# (infra/wait-healthy.sh). One-shot init jobs (oz-init, nrc-init, flowable-init)
# are not polled; they only need to have run. See docs/runbooks/gitea-actions-gotchas.md.
WAIT_SVCS := openzaak nrc-web acl bff
# Config files (OpenZaak data.yaml, Keycloak realms, Flowable BPMN) are streamed
# into external named volumes via `docker cp` (infra/seed-config.sh) instead of
@@ -58,16 +57,16 @@ unit:
dotnet test $(SLN) -c Release
## smoke: seed config, bring the whole stack up, wait for health-checked services, tear down
# SEED populates the external config volumes first (the upstream images are used
# verbatim — no build for them). `up -d --build` then starts EVERYTHING (building
# only our acl/bff). The second `up --wait` waits for the durable, health-checked
# services ($(WAIT_SVCS)); the one-shots are excluded because `--wait` fails when a
# one-shot with no `service_completed_successfully` dependant exits (flowable-init).
# Healthchecks run inside the containers, so no host port access is needed.
# SEED populates the external config volumes first (upstream images used verbatim;
# only our acl/bff are built). `up -d --build` starts EVERYTHING. Readiness is
# checked by infra/wait-healthy.sh polling the durable, health-checked services
# ($(WAIT_SVCS)) via `docker inspect` — portable across docker compose and
# podman-compose, and needing no `--wait` flag or host port access. The one-shots
# (oz-init, flowable-init) aren't polled; they just need to have run.
smoke:
$(SEED) oz kc fl
docker compose -f $(COMPOSE) up -d --build
bash -c 'docker compose -f $(COMPOSE) up -d --wait --wait-timeout 420 $(WAIT_SVCS); rc=$$?; docker compose -f $(COMPOSE) down --volumes; docker volume rm -f $(CFG_VOLS) >/dev/null 2>&1; exit $$rc'
bash -c 'WAIT_TIMEOUT=420 bash infra/wait-healthy.sh $(WAIT_SVCS); rc=$$?; docker compose -f $(COMPOSE) down --volumes; docker volume rm -f $(CFG_VOLS) >/dev/null 2>&1; exit $$rc'
## up: seed config volumes and start the full stack (use instead of bare
## `docker compose up`, which can't self-seed the external config volumes)