Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix(Dockerfile): healthcheck hits catch-all route instead of API — use /api/ping and verify response body#1582

Open
Yunaido wants to merge 2 commits intoevroon:masterfrom
Yunaido:fix/healthcheck-hits-catch-all-instead-of-api
Open

fix(Dockerfile): healthcheck hits catch-all route instead of API — use /api/ping and verify response body#1582
Yunaido wants to merge 2 commits intoevroon:masterfrom
Yunaido:fix/healthcheck-hits-catch-all-instead-of-api

Conversation

@Yunaido
Copy link

@Yunaido Yunaido commented Mar 1, 2026

Problem

The combined Dockerfile healthcheck uses /ping:

HEALTHCHECK --interval=3s --timeout=5s --retries=10 \
    CMD ["wget", "-O", "/dev/null", "http://0.0.0.0:8400/ping"]

This is broken in two ways when SERVE_FRONTEND=true:

1. Wrong path — always returns 200 regardless of API health

When SERVE_FRONTEND=true, FastAPI installs a catch-all route:

@app.get("/{full_path:path}")
async def frontend(full_path: str) -> FileResponse:
    return FileResponse(frontend_root / Path("index.html"))

Any path that doesn't match an API route — including /ping — is caught here
and returns index.html with HTTP 200. The healthcheck passes even if the
FastAPI app, database connection, or API router are completely broken.

The correct path is /api/ping, which is resolved by the API router (mounted
under API_PREFIX=/api) before the catch-all, and only returns 200 when the
backend is genuinely alive.

2. No response body verification

Even with the correct path, wget -O /dev/null discards the response body.
A 200 from the catch-all would still pass. Checking for "ping" in the
response body proves the actual FastAPI endpoint responded — not just that
something returned 200.

3. Interval too aggressive

interval=3s with retries=10 means Docker marks a container unhealthy after
30 seconds of any hiccup, and hammers the endpoint every 3 seconds in normal
operation. 30s/5s/5 retries is standard production behaviour.

Fix

-HEALTHCHECK --interval=3s --timeout=5s --retries=10 \
-    CMD ["wget", "-O", "/dev/null", "http://0.0.0.0:8400/ping"]
+HEALTHCHECK --interval=30s --timeout=5s --retries=5 --start-period=30s \
+    CMD wget -O - http://0.0.0.0:8400/api/ping | grep -q '"ping"'
  • Path changed to /api/ping — hits the real FastAPI endpoint, not the catch-all
  • Response body verified — grep -q '"ping"' ensures the API actually responded
  • Interval relaxed to 30s with a 30s start period — standard production values

@Yunaido Yunaido marked this pull request as ready for review March 1, 2026 18:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant