#!/bin/bash set -euo pipefail log() { echo "[IntegraChat][$(date -Iseconds)] $*" } API_PORT="${API_PORT:-8000}" MCP_PORT="${MCP_PORT:-8900}" GRADIO_PORT="${GRADIO_PORT:-7860}" export API_PORT MCP_PORT GRADIO_PORT LOG_DIR="/app/logs" mkdir -p "${LOG_DIR}" log "Container starting. Python: $(python --version 2>&1)" log "API_PORT=${API_PORT}, MCP_PORT=${MCP_PORT}, GRADIO_PORT=${GRADIO_PORT}" cleanup() { log "Received termination signal. Stopping services..." # Kill child processes (only if they exist) [ -n "${MCP_PID:-}" ] && kill "${MCP_PID}" 2>/dev/null || true [ -n "${API_PID:-}" ] && kill "${API_PID}" 2>/dev/null || true [ -n "${GRADIO_PID:-}" ] && kill "${GRADIO_PID}" 2>/dev/null || true [ -n "${TAIL_PID:-}" ] && kill "${TAIL_PID}" 2>/dev/null || true wait || true log "All services stopped. Exiting." } trap cleanup SIGTERM SIGINT # Start MCP server log "Starting MCP server..." python -m backend.mcp_server.server > "${LOG_DIR}/mcp.log" 2>&1 & MCP_PID=$! # Give MCP a moment sleep 2 # Start FastAPI backend log "Starting FastAPI backend..." uvicorn backend.api.main:app --host 0.0.0.0 --port "${API_PORT}" > "${LOG_DIR}/fastapi.log" 2>&1 & API_PID=$! # Check if FastAPI process started sleep 2 if ! kill -0 "${API_PID}" 2>/dev/null; then log "ERROR: FastAPI process died immediately. Last 20 lines of log:" tail -n 20 "${LOG_DIR}/fastapi.log" || true exit 1 fi # Wait for FastAPI to become healthy log "Waiting for FastAPI health endpoint..." for attempt in {1..60}; do if curl -fsS "http://127.0.0.1:${API_PORT}/health" >/dev/null 2>&1; then log "FastAPI backend is healthy." break fi # Check if process is still running if ! kill -0 "${API_PID}" 2>/dev/null; then log "ERROR: FastAPI process died. Last 20 lines of log:" tail -n 20 "${LOG_DIR}/fastapi.log" || true exit 1 fi sleep 1 if [ $((attempt % 10)) -eq 0 ]; then log "FastAPI not ready yet (attempt ${attempt}/60). Last 5 lines of log:" tail -n 5 "${LOG_DIR}/fastapi.log" || true else log "FastAPI not ready yet (attempt ${attempt}/60)..." fi done # Final check if ! curl -fsS "http://127.0.0.1:${API_PORT}/health" >/dev/null 2>&1; then log "WARNING: FastAPI health check failed after 60 attempts. Last 30 lines of log:" tail -n 30 "${LOG_DIR}/fastapi.log" || true log "Continuing anyway..." fi # Start Gradio UI (foreground) log "Starting Gradio UI on port ${GRADIO_PORT}..." # Set DOCKER_CONTAINER flag so app.py knows not to auto-start services export DOCKER_CONTAINER=1 python app.py > "${LOG_DIR}/gradio.log" 2>&1 & GRADIO_PID=$! log "All services launched. Streaming logs (Ctrl+C to stop)..." tail -n 50 -F "${LOG_DIR}/"*.log & TAIL_PID=$! wait "${GRADIO_PID}" cleanup