From 0583f2920507c6255b0e0af2389b829139dfc06e Mon Sep 17 00:00:00 2001 From: lunarthegrey Date: Fri, 24 Apr 2026 07:09:30 -0500 Subject: [PATCH] Switch Ghost healthcheck to nc (BusyBox wget lacks --max-redirect) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous fix used `wget --spider -S --max-redirect=0` to stop wget from following Ghost's http→https redirect. That works on GNU wget but fails on the BusyBox wget shipped in ghost:6-alpine — BusyBox wget doesn't recognize --max-redirect, errors out on the unknown option, and the healthcheck never passes. Container stayed in "health: starting" forever. `nc -z localhost 2368` is a plain TCP port check — universally available via BusyBox, doesn't care about HTTP semantics, answers the only question that matters: is Ghost listening? If the process is up and the port is bound, nc exits 0 and Docker marks healthy. If Ghost crashes or the port isn't bound, nc exits non-zero and Traefik pulls the backend. Side benefit: it's also much faster than an HTTP request. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/scripts/patch.py | 11 +++++------ .github/scripts/test-patch.sh | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/scripts/patch.py b/.github/scripts/patch.py index 07c652a..32bb3ec 100644 --- a/.github/scripts/patch.py +++ b/.github/scripts/patch.py @@ -157,12 +157,11 @@ def patch_compose() -> None: " env_file:\n" " - .env\n" " healthcheck:\n" - # Ghost redirects http→https when the Host header doesn't match its - # configured url, so a naive wget follows back out through Traefik - # and dies on setups without hairpin NAT. --max-redirect=0 stops - # the follow; we accept any HTTP response line as "Ghost is up". - ' test: ["CMD-SHELL", "wget --spider -S --max-redirect=0 -T 3 ' - "http://localhost:2368/ghost/api/admin/site/ 2>&1 | grep -q 'HTTP/1'\"]\n" + # TCP port check. BusyBox (Alpine) wget doesn't support + # --max-redirect, so the HTTP-response approach fails; nc -z is + # universally available and answers the only question that matters + # for readiness: is Ghost listening on 2368? + ' test: ["CMD", "nc", "-z", "localhost", "2368"]\n' " interval: 30s\n" " timeout: 5s\n" " retries: 5\n" diff --git a/.github/scripts/test-patch.sh b/.github/scripts/test-patch.sh index c2fd89d..1e45691 100755 --- a/.github/scripts/test-patch.sh +++ b/.github/scripts/test-patch.sh @@ -43,7 +43,7 @@ grep -q 'SERVICE_URL_ANALYTICS_3000: ""' compose.yml grep -q 'SERVICE_URL_ACTIVITYPUB_8080: ""' compose.yml echo "→ assert Ghost healthcheck injected" -grep -q 'localhost:2368/ghost/api/admin/site' compose.yml +grep -q '"nc", "-z", "localhost", "2368"' compose.yml echo "→ assert mail vars exposed to Coolify UI" # shellcheck disable=SC2016 # literal compose ${...} syntax, no shell expansion wanted