#!/usr/bin/env bash # Run on the server from repo root with the stack up: # bash scripts/check-prod-stack.sh # Verifies Postgres, MinIO, and be0 /health; be0 → postgres:5432 and minio:9000 reachability. set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" COMPOSE=(docker compose --env-file "${ROOT}/.env" -f "${ROOT}/docker-compose.prod.yml") cd "$ROOT" if [[ ! -f "${ROOT}/.env" ]]; then printf 'Missing %s\n' "${ROOT}/.env" >&2 exit 1 fi set -a # shellcheck disable=SC1090 source "${ROOT}/.env" set +a echo "=== Compose ps ===" "${COMPOSE[@]}" ps echo "" echo "=== Postgres (pg_isready inside postgres container) ===" "${COMPOSE[@]}" exec -T postgres pg_isready -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" echo "" echo "=== MinIO health (inside minio container) ===" "${COMPOSE[@]}" exec -T minio curl -sf "http://127.0.0.1:9000/minio/health/live" >/dev/null echo "OK" echo "" echo "=== be0 /health ===" "${COMPOSE[@]}" exec -T be0 curl -sf "http://127.0.0.1:4402/health" >/dev/null echo "OK" echo "" echo "=== be0 → postgres:5432 (TCP) ===" "${COMPOSE[@]}" exec -T be0 python -c "import socket; s=socket.create_connection(('postgres',5432),3); s.close()" echo "OK" echo "" echo "=== be0 → minio:9000 (HTTP) ===" "${COMPOSE[@]}" exec -T be0 curl -sf "http://minio:9000/minio/health/live" >/dev/null echo "OK" echo "" echo "=== frontends serving (nginx static builds) ===" for svc_port in \ "frontend_user:${FE_PORT}" \ "frontend_admin:${FE_ADMIN_PORT:-8082}" \ "frontend_investigator:${FE_INV_PORT:-8083}" \ "frontend_publisher:${FE_PUB_PORT:-8084}"; do svc="${svc_port%%:*}"; port="${svc_port##*:}" code=$(curl -s -m5 -o /dev/null -w '%{http_code}' "http://127.0.0.1:${port}" || echo 000) echo " ${svc} :${port} -> ${code}" [[ "$code" == "200" ]] || { echo " ${svc} not serving (HTTP ${code})"; exit 1; } done echo "" printf 'Done. If be0 /health failed, read logs: docker compose --env-file .env -f docker-compose.prod.yml logs be0\n' printf 'Typical cloud issue: POSTGRES_PASSWORD in .env does not match the first-init Postgres volume — see docs/deploy-production-docker.md\n'