#!/usr/bin/env bash # server/healthcheck.sh # # Fiche #21 (prod): healthcheck multi-composants. # - API upload (FastAPI) # - Dashboard (Flask) # - Worker externe (heartbeat file) # - Disque (minimum free) set -euo pipefail API_HOST="${RPA_API_HOST:-127.0.0.1}" API_PORT="${RPA_API_PORT:-8000}" DASH_HOST="${RPA_DASHBOARD_HOST:-127.0.0.1}" DASH_PORT="${RPA_DASHBOARD_PORT:-5001}" CHECK_DASHBOARD="${RPA_CHECK_DASHBOARD:-1}" HEARTBEAT_PATH="${RPA_WORKER_HEARTBEAT_PATH:-data/runtime/health/worker_heartbeat.json}" HEARTBEAT_MAX_AGE_S="${RPA_WORKER_HEARTBEAT_MAX_AGE_S:-60}" MIN_FREE_MB="${RPA_MIN_FREE_MB:-1024}" fail() { echo "❌ $1" >&2 exit 2 } # --- API --- curl -fsS --max-time 2 "http://${API_HOST}:${API_PORT}/healthz" >/dev/null \ || fail "API healthz unreachable (http://${API_HOST}:${API_PORT}/healthz)" # --- Dashboard (optionnel) --- if [[ "${CHECK_DASHBOARD}" == "1" ]]; then curl -fsS --max-time 2 "http://${DASH_HOST}:${DASH_PORT}/healthz" >/dev/null \ || fail "Dashboard healthz unreachable (http://${DASH_HOST}:${DASH_PORT}/healthz)" fi # --- Worker heartbeat (optionnel) --- if [[ -f "${HEARTBEAT_PATH}" ]]; then # age in seconds now=$(date +%s) mtime=$(stat -c %Y "${HEARTBEAT_PATH}" 2>/dev/null || echo 0) age=$((now - mtime)) if (( age > HEARTBEAT_MAX_AGE_S )); then fail "Worker heartbeat too old: ${age}s (> ${HEARTBEAT_MAX_AGE_S}s)" fi fi # --- Disk space --- free_kb=$(df -Pk . | awk 'NR==2 {print $4}') free_mb=$((free_kb / 1024)) if (( free_mb < MIN_FREE_MB )); then fail "Low disk space: ${free_mb}MB free (< ${MIN_FREE_MB}MB)" fi echo "✅ healthcheck ok"