#!/usr/bin/env bash set -euo pipefail # ─── Color output ────────────────────────────────────────────── RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' CYAN='\033[0;36m' NC='\033[0m' info() { echo -e "${CYAN}[INFO]${NC} $*"; } ok() { echo -e "${GREEN}[OK]${NC} $*"; } warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } error() { echo -e "${RED}[ERROR]${NC} $*"; } header() { echo -e "\n${YELLOW}─── $* ───${NC}"; } EXIT_CODE=0 # ─── Docker service health ────────────────────────────────────── header "Docker Container Status" containers=$(docker ps --format "{{.Names}}" 2>/dev/null || true) if [ -z "${containers}" ]; then warn "No running Docker containers found" else while IFS= read -r name; do status=$(docker inspect --format='{{.State.Status}}' "${name}" 2>/dev/null || echo "unknown") health=$(docker inspect --format='{{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}}' "${name}" 2>/dev/null || echo "none") if [ "${status}" = "running" ]; then if [ "${health}" = "healthy" ]; then ok "${name} — running, healthy" elif [ "${health}" = "unhealthy" ]; then error "${name} — running but UNHEALTHY" EXIT_CODE=1 else warn "${name} — running (no health check)" fi else error "${name} — ${status}" EXIT_CODE=1 fi done <<< "${containers}" fi # ─── HTTP health endpoints ─────────────────────────────────────── header "HTTP Health Endpoints" check_endpoint() { local name="$1" local url="$2" local expected_code="${3:-200}" if command -v curl &>/dev/null; then http_code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 "${url}" 2>/dev/null || echo "000") elif command -v wget &>/dev/null; then http_code=$(wget --server-response --spider --timeout=5 "${url}" 2>&1 | awk '/HTTP\/1.1/{print $2}' | tail -1 || echo "000") else warn "Neither curl nor wget available — skipping HTTP checks" return fi if [ "${http_code}" = "${expected_code}" ] || [ "${http_code}" = "000" ]; then if [ "${http_code}" = "000" ]; then warn "${name} — could not connect to ${url}" else ok "${name} — ${url} returned ${http_code}" fi else error "${name} — ${url} returned ${http_code} (expected ${expected_code})" EXIT_CODE=1 fi } check_endpoint "API" "http://localhost:3001/health" check_endpoint "Web" "http://localhost:80/" check_endpoint "CMS" "http://localhost:3000/health" check_endpoint "MinIO (API)" "http://localhost:9000/minio/health/live" check_endpoint "MinIO (Console)" "http://localhost:9001/" # ─── Port check ───────────────────────────────────────────────── header "Port Availability" check_port() { local name="$1" local port="$2" if command -v nc &>/dev/null; then if nc -z localhost "${port}" 2>/dev/null; then ok "${name} — port ${port} is open" else error "${name} — port ${port} is CLOSED" EXIT_CODE=1 fi else # Fallback: try connecting with /dev/tcp (bash built-in) if timeout 1 bash -c "echo >/dev/tcp/localhost/${port}" 2>/dev/null; then ok "${name} — port ${port} is open" else error "${name} — port ${port} is CLOSED" EXIT_CODE=1 fi fi } check_port "PostgreSQL" 5432 check_port "Redis" 6379 # ─── Summary ──────────────────────────────────────────────────── echo "" if [ "${EXIT_CODE}" -eq 0 ]; then echo -e "${GREEN}══════════════════════════════════════════════════════════${NC}" echo -e "${GREEN} All services are healthy!${NC}" echo -e "${GREEN}══════════════════════════════════════════════════════════${NC}" else echo -e "${RED}══════════════════════════════════════════════════════════${NC}" echo -e "${RED} Some services have issues (exit code: ${EXIT_CODE})${NC}" echo -e "${RED}══════════════════════════════════════════════════════════${NC}" fi exit "${EXIT_CODE}"