scripts/health-check.sh

#!/usr/bin/env bash
# Curl each homelab service's health endpoint and report.
# Exit code: 0 all ok, 1 one failure, 2 multiple failures.
# Cron runs this every 5 minutes; non-zero triggers a mail.
# See mercemay.top/src/homelab-compose/ for the stack.
set -euo pipefail

# Each entry: "name url expected_status"
targets=(
	"jellyfin    http://jellyfin.homelab.local/health           200"
	"immich      http://photos.homelab.local/api/server/ping    200"
	"paperless   http://docs.homelab.local/                     200"
	"gitea       http://git.homelab.local/api/healthz           200"
	"syncthing   http://sync.homelab.local/rest/noauth/health   200"
	"pihole      http://dns.homelab.local/admin/                200"
	"prometheus  http://prometheus.homelab.local/-/healthy      200"
	"grafana     http://grafana.homelab.local/api/health        200"
)

failures=0
report=()

check() {
	local name="$1" url="$2" want="$3"
	local got
	got="$(curl -sS -o /dev/null -w '%{http_code}' --max-time 8 "$url" || echo "000")"
	if [[ "$got" == "$want" ]]; then
		report+=("  OK   $name ($got)")
	else
		report+=("  FAIL $name want=$want got=$got  url=$url")
		failures=$((failures+1))
	fi
}

for row in "${targets[@]}"; do
	# shellcheck disable=SC2086
	set -- $row
	check "$1" "$2" "$3"
done

printf 'homelab health @ %s\n' "$(date -Iseconds)"
for line in "${report[@]}"; do
	printf '%s\n' "$line"
done

if (( failures == 0 )); then
	exit 0
elif (( failures == 1 )); then
	exit 1
else
	exit 2
fi