The health check endpoint now properly indicates service unavailability: - Returns HTTP 200 when fail2ban is online - Returns HTTP 503 when fail2ban is offline This allows Docker and other orchestration tools to correctly detect when fail2ban is unreachable and automatically restart the backend container, preventing the situation where Docker treats the container as healthy despite fail2ban being down. Changes: - Update GET /api/health to return 503 on fail2ban offline - Return appropriate JSON response bodies for each state - Update tests to verify both online (200) and offline (503) scenarios - Update Dockerfile HEALTHCHECK documentation - Add Health Checks section to Deployment.md documentation All tests pass with 100% coverage on health.py. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
44 lines
1.5 KiB
Python
44 lines
1.5 KiB
Python
"""Health check router.
|
|
|
|
A lightweight ``GET /api/health`` endpoint that verifies the application
|
|
is running and can serve requests. Also reports the cached fail2ban liveness
|
|
state so monitoring tools and Docker health checks can observe daemon status
|
|
without probing the socket directly.
|
|
"""
|
|
|
|
from fastapi import APIRouter, status
|
|
from fastapi.responses import JSONResponse
|
|
|
|
from app.dependencies import ServerStatusDep
|
|
|
|
router: APIRouter = APIRouter(prefix="/api", tags=["Health"])
|
|
|
|
|
|
@router.get("/health", summary="Application health check")
|
|
async def health_check(server_status: ServerStatusDep) -> JSONResponse:
|
|
"""Return application and fail2ban status.
|
|
|
|
Returns HTTP 200 if fail2ban is online, HTTP 503 if offline.
|
|
Docker health checks interpret 503 as unhealthy and restart the container
|
|
if fail2ban remains unreachable, ensuring the backend only runs when
|
|
fail2ban is available.
|
|
|
|
Args:
|
|
server_status: Injected cached server status snapshot.
|
|
|
|
Returns:
|
|
HTTP 200 with ``{"status": "ok", "fail2ban": "online"}`` if healthy,
|
|
or HTTP 503 with ``{"status": "unavailable", "fail2ban": "offline"}``
|
|
if fail2ban is unreachable.
|
|
"""
|
|
if not server_status.online:
|
|
return JSONResponse(
|
|
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
|
|
content={"status": "unavailable", "fail2ban": "offline"},
|
|
)
|
|
|
|
return JSONResponse(
|
|
status_code=status.HTTP_200_OK,
|
|
content={"status": "ok", "fail2ban": "online"},
|
|
)
|