hasari-api / scripts /dev-up.sh
erdoganpeker's picture
v0.3.0 — multimodal vehicle damage MVP
e327f0d
#!/usr/bin/env bash
# scripts/dev-up.sh
# ---------------------------------------------------------------------------
# Smoke up + health verification for the local docker compose stack.
#
# Usage (from repo root):
# ./scripts/dev-up.sh
# ./scripts/dev-up.sh --rebuild # force --build
# ./scripts/dev-up.sh --infra-only # only postgres/redis/minio
#
# What it does:
# 1. Pre-flight: docker daemon, port collisions (5432/6379/9000/9001/8000),
# ML model snapshot directory.
# 2. docker compose up -d (infra first, then backend + worker).
# 3. Poll health endpoints (postgres / redis / minio / backend).
# 4. Print summary URLs.
# ---------------------------------------------------------------------------
set -euo pipefail
REBUILD=0
INFRA_ONLY=0
for arg in "$@"; do
case "$arg" in
--rebuild) REBUILD=1 ;;
--infra-only) INFRA_ONLY=1 ;;
*) echo "unknown arg: $arg" >&2; exit 2 ;;
esac
done
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
cd "$REPO_ROOT"
c_cyan='\033[36m'; c_grn='\033[32m'; c_ylw='\033[33m'; c_red='\033[31m'; c_off='\033[0m'
section() { printf "\n${c_cyan}=== %s ===${c_off}\n" "$*"; }
ok() { printf " ${c_grn}ok:${c_off} %s\n" "$*"; }
warn() { printf " ${c_ylw}warn:${c_off} %s\n" "$*"; }
fail() { printf " ${c_red}FAIL:${c_off} %s\n" "$*"; }
port_free() {
local p="$1"
if command -v ss >/dev/null 2>&1; then
! ss -ltn "( sport = :$p )" 2>/dev/null | grep -q ":$p"
elif command -v lsof >/dev/null 2>&1; then
! lsof -iTCP:"$p" -sTCP:LISTEN >/dev/null 2>&1
else
return 0
fi
}
# ---------- 1. Pre-flight ----------
section "Pre-flight checks"
if ! docker info --format "{{.ServerVersion}}" >/dev/null 2>&1; then
fail "docker daemon not reachable. Start Docker / Docker Desktop."
exit 1
fi
ok "docker daemon reachable"
for p in 5432 6379 9000 9001 8000; do
if port_free "$p"; then
ok "port $p free"
else
warn "port $p is already in use on the host"
fi
done
DEFAULT_SNAPSHOT="$REPO_ROOT/services/ml/runs/bundles/full_20260515_044630/_SNAPSHOT_FOR_BUILD"
SNAPSHOT="${MODEL_SNAPSHOT_DIR:-$DEFAULT_SNAPSHOT}"
if [[ ! -d "$SNAPSHOT" ]]; then
warn "ML snapshot dir missing: $SNAPSHOT"
BUNDLE_ROOT="$REPO_ROOT/services/ml/runs/bundles"
if [[ -d "$BUNDLE_ROOT" ]]; then
CANDIDATE="$(find "$BUNDLE_ROOT" -maxdepth 1 -type d -name 'full_*' -printf '%T@ %p\n' 2>/dev/null \
| sort -nr | head -n1 | awk '{ $1=""; sub(/^ /, ""); print }')"
if [[ -n "${CANDIDATE:-}" && -d "$CANDIDATE/_SNAPSHOT_FOR_BUILD" ]]; then
export MODEL_SNAPSHOT_DIR="$CANDIDATE/_SNAPSHOT_FOR_BUILD"
ok "fallback snapshot dir set: $MODEL_SNAPSHOT_DIR"
else
warn "no _SNAPSHOT_FOR_BUILD under bundles/; backend will start without ML weights"
fi
fi
else
ok "model snapshot dir: $SNAPSHOT"
fi
# ---------- 2. Compose up ----------
section "docker compose up (infrastructure)"
docker compose up -d postgres redis minio minio-init
ok "infra services started"
if [[ "$INFRA_ONLY" -eq 0 ]]; then
section "docker compose up (backend + worker)"
if [[ "$REBUILD" -eq 1 ]]; then
docker compose up -d --build backend worker
else
docker compose up -d backend worker
fi
ok "backend + worker started"
fi
# ---------- 3. Health checks ----------
section "Health checks"
wait_for() {
local name="$1"; local timeout="$2"; shift 2
local deadline=$(( $(date +%s) + timeout ))
while [[ "$(date +%s)" -lt "$deadline" ]]; do
if "$@" >/dev/null 2>&1; then
ok "$name healthy"
return 0
fi
sleep 2
done
fail "$name did not become healthy within ${timeout}s"
return 1
}
all_healthy=0
wait_for "postgres" 60 docker exec hasarui-postgres pg_isready -U postgres -d arac_hasar || all_healthy=1
wait_for "redis" 30 bash -c 'test "$(docker exec hasarui-redis redis-cli ping)" = "PONG"' || all_healthy=1
wait_for "minio" 45 curl -fsS http://localhost:9000/minio/health/live || all_healthy=1
if [[ "$INFRA_ONLY" -eq 0 ]]; then
wait_for "backend /health" 180 curl -fsS http://localhost:8000/health || all_healthy=1
fi
# ---------- 4. Summary ----------
section "Summary"
docker compose ps
printf "\n${c_cyan}URLs:${c_off}\n"
echo " API health -> http://localhost:8000/health"
echo " API docs -> http://localhost:8000/docs"
echo " MinIO console -> http://localhost:9001 (minioadmin / minioadmin)"
echo " Postgres -> postgresql://postgres:postgres@localhost:5432/arac_hasar"
echo
echo "Next: pnpm --filter @arac-hasar/web dev # http://localhost:3000"
exit "$all_healthy"