Files
vplatform/start.sh
2026-04-09 09:43:21 +00:00

149 lines
3.2 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
RUN_DIR="$ROOT_DIR/.run"
LOG_DIR="$ROOT_DIR/logs"
BACKEND_PID_FILE="$RUN_DIR/backend.pid"
FRONTEND_PID_FILE="$RUN_DIR/frontend.pid"
BACKEND_LOG_FILE="$LOG_DIR/backend.log"
FRONTEND_LOG_FILE="$LOG_DIR/frontend.log"
BACKEND_HOST="${BACKEND_HOST:-0.0.0.0}"
BACKEND_PORT="${BACKEND_PORT:-8000}"
FRONTEND_HOST="${FRONTEND_HOST:-0.0.0.0}"
FRONTEND_PORT="${FRONTEND_PORT:-8451}"
CORS_ORIGINS="${CORS_ORIGINS:-http://localhost:${FRONTEND_PORT},http://127.0.0.1:${FRONTEND_PORT}}"
VITE_PROXY_TARGET="${VITE_PROXY_TARGET:-http://127.0.0.1:${BACKEND_PORT}}"
mkdir -p "$RUN_DIR" "$LOG_DIR"
require_command() {
if ! command -v "$1" >/dev/null 2>&1; then
echo "Missing command: $1" >&2
exit 1
fi
}
cleanup_stale_pid() {
local pid_file="$1"
if [[ -f "$pid_file" ]]; then
local pid
pid="$(cat "$pid_file")"
if [[ -n "$pid" ]] && kill -0 "$pid" >/dev/null 2>&1; then
return 0
fi
rm -f "$pid_file"
fi
return 1
}
wait_for_port() {
local host="$1"
local port="$2"
local name="$3"
local retries=30
while (( retries > 0 )); do
if python3 - "$host" "$port" <<'PY'
import socket
import sys
host = sys.argv[1]
port = int(sys.argv[2])
sock = socket.socket()
sock.settimeout(0.5)
try:
sock.connect((host, port))
except OSError:
sys.exit(1)
finally:
sock.close()
sys.exit(0)
PY
then
echo "$name is ready on ${host}:${port}"
return 0
fi
sleep 1
retries=$((retries - 1))
done
echo "$name failed to start on ${host}:${port}. Check logs in $LOG_DIR" >&2
return 1
}
require_command python3
require_command node
require_command npm
require_command ffmpeg
if ! python3 - <<'PY' >/dev/null 2>&1
import fastapi
import uvicorn
import multipart
PY
then
echo "Missing Python packages. Run: cd backend && python3 -m pip install --user -r requirements.txt" >&2
exit 1
fi
if [[ ! -d "$ROOT_DIR/frontend/node_modules" ]]; then
echo "Installing frontend dependencies..."
(
cd "$ROOT_DIR/frontend"
npm install
)
fi
if cleanup_stale_pid "$BACKEND_PID_FILE"; then
echo "Backend already running with PID $(cat "$BACKEND_PID_FILE")"
else
echo "Starting backend..."
(
cd "$ROOT_DIR/backend"
nohup env \
CORS_ORIGINS="$CORS_ORIGINS" \
python3 -m uvicorn app.main:app \
--host "$BACKEND_HOST" \
--port "$BACKEND_PORT" \
>"$BACKEND_LOG_FILE" 2>&1 &
echo $! > "$BACKEND_PID_FILE"
)
fi
wait_for_port "127.0.0.1" "$BACKEND_PORT" "backend"
if cleanup_stale_pid "$FRONTEND_PID_FILE"; then
echo "Frontend already running with PID $(cat "$FRONTEND_PID_FILE")"
else
echo "Starting frontend..."
(
cd "$ROOT_DIR/frontend"
nohup env \
VITE_PROXY_TARGET="$VITE_PROXY_TARGET" \
npm run dev -- --host "$FRONTEND_HOST" --port "$FRONTEND_PORT" \
>"$FRONTEND_LOG_FILE" 2>&1 &
echo $! > "$FRONTEND_PID_FILE"
)
fi
wait_for_port "127.0.0.1" "$FRONTEND_PORT" "frontend"
SERVER_IP="$(hostname -I 2>/dev/null | awk '{print $1}')"
if [[ -z "$SERVER_IP" ]]; then
SERVER_IP="127.0.0.1"
fi
cat <<EOF
VPlatform started in background.
Frontend: http://${SERVER_IP}:${FRONTEND_PORT}
Backend: http://${SERVER_IP}:${BACKEND_PORT}
Logs:
$BACKEND_LOG_FILE
$FRONTEND_LOG_FILE
EOF