File size: 3,469 Bytes
6ca4b94 |
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 |
#!/usr/bin/env bash
set -Eeuo pipefail
DEV_MODE="${DEV_MODE:-false}"
MAIN_HOST="${HOST:-0.0.0.0}"
MAIN_PORT="${PORT:-7860}"
MODEL_HOST="${MODEL_HOST:-0.0.0.0}"
MODEL_PORT="${MODEL_PORT:-8001}"
TAILWIND_BIN="/app/bin/tailwindcss"
TAILWIND_IN="/app/public/styles/input.css"
TAILWIND_OUT="/app/public/styles/output.css"
log() { printf "%s %s\n" "$(date +'%Y-%m-%dT%H:%M:%S%z')" "$*"; }
ensure_tailwind() {
if [[ -x "${TAILWIND_BIN}" ]]; then
log "Tailwind CSS found at ${TAILWIND_BIN}"
return
fi
log "Tailwind CSS not found, downloading binary..."
mkdir -p /app/bin
local os arch
os="$(uname -s | tr '[:upper:]' '[:lower:]')"
arch="$(uname -m)"
case "${os}" in
darwin) os="macos" ;;
linux) os="linux" ;;
*) log "Unsupported OS: ${os}"; exit 1 ;;
esac
case "${arch}" in
x86_64|amd64) arch="x64" ;;
arm64|aarch64) arch="arm64" ;;
*) log "Unsupported arch: ${arch}"; exit 1 ;;
esac
curl -sSLo "${TAILWIND_BIN}" \
"https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-${os}-${arch}"
chmod +x "${TAILWIND_BIN}"
}
build_tailwind() {
if [[ "${DEV_MODE}" == "true" ]]; then
log "Building Tailwind (initial)..."
"${TAILWIND_BIN}" -i "${TAILWIND_IN}" -o "${TAILWIND_OUT}"
log "Starting Tailwind in watch mode (dev)..."
"${TAILWIND_BIN}" -i "${TAILWIND_IN}" -o "${TAILWIND_OUT}" --watch=always --poll &
export TAILWIND_PID=$!
else
log "Building Tailwind (prod)..."
"${TAILWIND_BIN}" -i "${TAILWIND_IN}" -o "${TAILWIND_OUT}" --minify
fi
}
download_dataset() {
if ! PYTHONPATH=/app poetry run python /app/scripts/download_dataset.py; then
log "WARN: dataset download failed; continuing without cached dataset."
fi
}
start_model_server() {
if [[ "${DEV_MODE}" == "true" ]]; then
log "DEV mode: NOT starting model server. Open VS Code and press F5 (Run and Debug) to launch it."
return 0
fi
if [[ -n "${MODEL__ITEM_MODEL_PATH:-}" || -n "${MODEL__SCALE_MODEL_PATH:-}" ]]; then
log "Starting model server on ${MODEL_HOST}:${MODEL_PORT}..."
poetry run uvicorn src.servers.model_server:app \
--host "${MODEL_HOST}" \
--port "${MODEL_PORT}" \
--workers "${MODEL_WORKERS:-1}" &
export MODEL_PID=$!
else
log "Model paths not configured — NOT starting model server."
fi
}
start_main_app() {
if [[ "${DEV_MODE}" == "true" ]]; then
log "DEV mode: NOT starting main FastAPI app. Open VS Code and press F5 (Run and Debug) to launch it."
return 0
fi
log "PROD mode: starting Gunicorn (Uvicorn worker) on ${MAIN_HOST}:${MAIN_PORT}..."
exec poetry run gunicorn src.main:app \
-k uvicorn.workers.UvicornWorker \
-w "${WEB_CONCURRENCY:-2}" \
-b "${MAIN_HOST}:${MAIN_PORT}"
}
cleanup() {
log "Shutting down..."
if [[ -n "${TAILWIND_PID:-}" ]]; then
log "Stopping Tailwind (PID ${TAILWIND_PID})"
kill "${TAILWIND_PID}" 2>/dev/null || true
fi
if [[ -n "${MODEL_PID:-}" ]]; then
log "Stopping model server (PID ${MODEL_PID})"
kill "${MODEL_PID}" 2>/dev/null || true
fi
}
trap cleanup SIGINT SIGTERM
if [[ "${DEV_MODE}" == "true" ]]; then
log "Starting services in DEVELOPMENT mode..."
else
log "Starting services in PRODUCTION mode..."
fi
ensure_tailwind
download_dataset
build_tailwind
start_model_server
start_main_app
if [[ "${DEV_MODE}" == "true" ]]; then
log "Dev services running. Press Ctrl+C to stop."
wait
fi |