File size: 4,784 Bytes
e327f0d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/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"