worker container is permanently unhealthy — it inherits the API image's HTTP healthcheck but serves no HTTP #156
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found immediately after the #155 cutover. Both hosts show it:
Cause
The
workerservice runs the API image with a different command (node dist/worker.js), so it inherits that image'sHEALTHCHECK— api/Dockerfile:41:The worker process does not listen on 3000. It has no HTTP surface at all. So the probe cannot ever succeed:
The worker itself is fine — this is a false negative, not a broken worker:
Why it's latent until now
#117 added the
workerservice, but nothing ever synced the compose file to a host (#155) — so this is the first time the worker container has ever run anywhere. The defect shipped with #117 and has been invisible for a month.Why it matters
Nothing depends on the worker via
condition: service_healthy, so there is no cascade and no outage. The cost is monitoring integrity:Rhoving/iac-repohas an open issue for a blackbox/healthprobe + Prometheus alerting on this stack, and cAdvisor-based container-health alerting would fire on this permanently.Options
workerservice (healthcheck: {disable: true}in the Ansible compose template). Honest and one line — the container genuinely has no HTTP surface. But it trades a false red for no signal at all, and per the point above, "no signal" is what makes a dead worker invisible.worker.tson its own port serving/health, or aCMDthat checks BullMQ liveness (e.g. the worker heartbeats a Redis key and the probe asserts freshness). More work, and it's the one that actually answers the question.Leaning (2) with a Redis heartbeat — it needs no new port and directly tests the thing that matters (the worker is consuming). (1) is a reasonable stopgap in the same change if (2) isn't wanted now, but shipping (1) alone should be a deliberate decision, not the default.
The fix lands in this repo (Dockerfile and/or
worker.ts); the compose-side half is inRhoving/iac-repo→tealeaves-ansible/roles/tealeaves/templates/docker-compose.yml.j2.Refs #117, #155, Rhoving/iac-repo#319
Auto-closed by
2710a9f. Reopening — the app-side half is done and verified, but the container is stillunhealthyon both hosts, which is what this issue is actually about.Verified working on dev
Dev's Watchtower picked up the new
:betawithin ~2 minutes. The heartbeat and probe both do what they should:Chose option 2 from the list above, with the Redis variant rather than an HTTP listener: no new port, and it tests the thing the container is actually for. A file-on-disk heartbeat was the tempting shortcut and is the wrong shape — it would keep ticking from a timer while Redis was unreachable and nothing was being consumed, reporting healthy for precisely the failure worth catching.
Still outstanding
The container reports
unhealthyregardless, because Docker is still running the inherited probe — the compose-side override isRhoving/iac-repo#325, open and not yet merged.:beta9.4.0Prod needs a release tag containing
2710a9fand itstealeaves_{api,app}_imagepin bumped before it clears. Not a regression in the meantime — the probe fails file-not-found instead of connection-refused, and it was already red.Closing this again once both hosts show
healthy.