File size: 3,073 Bytes
ce16368
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1a3b54d
ce16368
 
 
 
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
#!/bin/bash
# start.sh β€” TisTru startup script for Hugging Face Spaces
# Starts: Ollama (LLM server) β†’ pulls model β†’ FastAPI backend β†’ Next.js frontend
# Everything funnels through a single port (7860) via FastAPI static file serving
# or a reverse proxy pattern.

set -euo pipefail

PORT="${PORT:-7860}"
OLLAMA_MODEL="${OLLAMA_MODEL:-llama3.1}"
OLLAMA_BASE_URL="${OLLAMA_BASE_URL:-http://localhost:11434/v1}"
USE_LOCAL_LLM="${USE_LOCAL_LLM:-true}"

echo "========================================"
echo "  TisTru β€” Starting services"
echo "  Port     : $PORT"
echo "  LLM mode : $USE_LOCAL_LLM"
echo "  Model    : $OLLAMA_MODEL"
echo "========================================"

# ── 1. Start Ollama in background (only in local LLM mode) ───────────────────
if [ "$USE_LOCAL_LLM" = "true" ]; then
    echo "[1/4] Starting Ollama daemon..."
    ollama serve &
    OLLAMA_PID=$!

    # Wait until Ollama API is reachable (up to 30 s)
    echo "[1/4] Waiting for Ollama to be ready..."
    for i in $(seq 1 30); do
        if curl -sf http://localhost:11434/ > /dev/null 2>&1; then
            echo "[1/4] Ollama is ready."
            break
        fi
        if [ "$i" -eq 30 ]; then
            echo "[ERROR] Ollama did not start within 30 seconds. Exiting."
            exit 1
        fi
        sleep 1
    done

    # ── 2. Pull the model if not already cached ──────────────────────────────
    echo "[2/4] Pulling model '$OLLAMA_MODEL' (skipped if already cached)..."
    ollama pull "$OLLAMA_MODEL"
    echo "[2/4] Model ready."
else
    echo "[1/4] USE_LOCAL_LLM=false β€” skipping Ollama startup."
    echo "[2/4] Skipping model pull."
fi

# ── 3. Start Next.js frontend in background ───────────────────────────────────
# The standalone build runs its own Node server on port 3000 internally.
# FastAPI (or a reverse proxy in start.sh) forwards /  requests to it.
NEXT_PORT=3000
echo "[3/4] Starting Next.js frontend on internal port $NEXT_PORT..."
cd /app/frontend
HOSTNAME=0.0.0.0 PORT=$NEXT_PORT node server.js &
NEXT_PID=$!
cd /app

# Wait for Next.js to be ready
for i in $(seq 1 20); do
    if curl -sf http://localhost:$NEXT_PORT/ > /dev/null 2>&1; then
        echo "[3/4] Next.js is ready."
        break
    fi
    if [ "$i" -eq 20 ]; then
        echo "[WARN] Next.js did not respond within 20 seconds β€” continuing anyway."
    fi
    sleep 1
done

# ── 4. Start FastAPI backend (foreground, keeps container alive) ──────────────
# FastAPI listens on 0.0.0.0:7860 and serves the API.
# Static/frontend requests are reverse-proxied to Next.js on port 3000
# via the proxy logic in backend/app/main.py (or handled by a middleware).
echo "[4/4] Starting FastAPI backend on port $PORT..."
exec env PYTHONPATH=/app/backend uvicorn backend.app.main:app \
    --host 0.0.0.0 \
    --port "$PORT" \
    --workers 1 \
    --log-level info