Commit 126c003
Harden healthcheck.sh and fix container-test.yaml for apps failing in the PR queue (#1815)
Docker healthchecks were hanging or mis-failing for many apps, causing
most "never healthy" CI failures on renovate PRs. Two root causes:
`check_http` in `include/healthcheck.sh` had no curl timeout and
required an exact `statusCode` match, and several apps'
`container-test.yaml` files relied on the default entrypoint staying
alive when it doesn't.
## Phase 1 — `include/healthcheck.sh`
- `check_http`: added `--connect-timeout 5 --max-time 10` to curl;
accept any 2xx/3xx when `statusCode:` is omitted, keep exact match when
set.
- `check_tcp`: wrapped the `/dev/tcp` probe in `timeout 5` so a hung
endpoint fails fast.
- YAML parsing: normalized whitespace between `-` and `port:` so `-
port: 8080` / tab-indented entries still register checks.
- Kept `exit 0 when CHECKS_RUN=0` behavior for
`filePaths`/`runners`-only files, but now warn to stderr when an
`http:`/`tcp:`/`healthCommands:` section was present and produced zero
checks.
- `healthCommands:` behavior unchanged.
## Phase 2 — healthcheck test scripts
- `scripts/test-healthcheck-positive.sh`: added a case where
`statusCode:` is omitted and the server returns 302 (default-accept
2xx/3xx), and a case using varied whitespace (`- port: '8080'`).
- `scripts/test-healthcheck-negative.sh`: added a case where
`statusCode: 200` is explicit and the server returns 302 (explicit
mismatch must still fail).
## Phase 3 — per-app `container-test.yaml`
Selection was driven by the open PR queue: collected every PR whose
`Build <app> / Test` job was failing, inspected each job log, and
grouped by failure mode.
- **Pin actual status code**
- `jackett`: `statusCode: 200` → `302` (redirects `/` to `/UI/Login`).
- **Switch to `runners:` with an entrypoint override** — for apps where
the default container entrypoint crashes, exits immediately, or depends
on runtime privileges, so the check itself becomes the container command
and no long-lived process is required:
- `python`, `kometa`, `actions-runner`, `doplarr`, `cni-plugins`,
`qbitmanage`, `code-server`, `sealskin`, `pylon`, `raneto`, `wud`
- `watchtower` (was `/app/watchtower --health-check`, which needs a
running service)
- `gluetun` (iptables probe needs CAP_NET_ADMIN not granted in test env)
- `cloudflareddns` (upstream no longer emits the `expectedOutput`
string)
- **Intentionally unchanged**: `tautulli`, `overseerr`, `emby`,
`home-assistant`. These had `http:/` with no `statusCode:` and failed
with `context deadline exceeded` caused by the pre-Phase-1 curl hang;
the Phase 1 changes (timeouts + default 2xx/3xx) address the failure
mode without per-app edits.
Example of the switch:
```yaml
# before
filePaths:
- /app/qbit_manage.py
# after — bypasses the broken upstream /start.sh entrypoint
runners:
- entrypoint: test -f /app/qbit_manage.py
```
## Not addressed
Forgetool behavior (external repo), `go.mod`/`go.sum`, and any unrelated
`apps/<app>/` refactors are out of scope per the plan.
---------
Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: Crow-Control <[email protected]>1 parent 2085130 commit 126c003
18 files changed
Lines changed: 168 additions & 53 deletions
File tree
- apps
- actions-runner
- cloudflareddns
- cni-plugins
- code-server
- doplarr
- gluetun
- jackett
- kometa
- pylon
- python
- qbitmanage
- raneto
- sealskin
- watchtower
- wud
- include
- scripts
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
4 | | - | |
5 | | - | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
5 | | - | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
4 | | - | |
| 3 | + | |
| 4 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
5 | | - | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
4 | | - | |
5 | 3 | | |
6 | | - | |
7 | | - | |
| 4 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
| 6 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
5 | | - | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
4 | | - | |
| 3 | + | |
| 4 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
5 | | - | |
| 4 | + | |
| 5 | + | |
0 commit comments