1
0

manage_services.sh 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #!/bin/bash
  2. # ==============================================================================
  3. # $Id$
  4. # File: manage_services.sh
  5. # Purpose: Comprehensive Service Manager for Local Food AI development.
  6. # Allows operators and developers to cleanly start, stop, restart,
  7. # and inspect all project elements in sequential order of dependencies
  8. # without triggering online data ingestion pipelines.
  9. # ==============================================================================
  10. # Exit immediately if a command exits with a non-zero status (except when checked)
  11. set -e
  12. # Sequence priority rules:
  13. # STARTUP: 1. MySQL -> 2. Ollama & SearXNG -> 3. Streamlit App & Nginx Proxy -> 4. Zabbix & Airflow
  14. # SHUTDOWN: 1. Zabbix & Airflow -> 2. Nginx & App -> 3. SearXNG & Ollama -> 4. MySQL
  15. COMPOSE_FILE="docker-compose.yml"
  16. # Colors for output logging
  17. GREEN='\033[0;32m'
  18. BLUE='\033[0;34m'
  19. YELLOW='\033[1;33m'
  20. RED='\033[0;31m'
  21. NC='\033[0m' # No Color
  22. log_info() {
  23. echo -e "${BLUE}[INFO] $(date '+%Y-%m-%d %H:%M:%S') - $1${NC}"
  24. }
  25. log_success() {
  26. echo -e "${GREEN}[SUCCESS] $(date '+%Y-%m-%d %H:%M:%S') - $1${NC}"
  27. }
  28. log_warn() {
  29. echo -e "${YELLOW}[WARNING] $(date '+%Y-%m-%d %H:%M:%S') - $1${NC}"
  30. }
  31. log_error() {
  32. echo -e "${RED}[ERROR] $(date '+%Y-%m-%d %H:%M:%S') - $1${NC}"
  33. }
  34. # Verify Docker Compose file exists
  35. if [ ! -f "$COMPOSE_FILE" ]; then
  36. log_error "Docker Compose file ($COMPOSE_FILE) not found in the current directory."
  37. exit 1
  38. fi
  39. start_services() {
  40. log_info "Initiating sequential startup sequence for development..."
  41. # Step 1: Start MySQL Database
  42. log_info "Step 1/4: Starting MySQL Database Container..."
  43. docker compose -f "$COMPOSE_FILE" up -d mysql
  44. # Wait for MySQL to become fully ready and accept connections
  45. log_info "Waiting for MySQL database socket to be available..."
  46. until docker compose -f "$COMPOSE_FILE" exec mysql mysqladmin ping -h"localhost" -u"root" -p"BTSai123" --silent; do
  47. sleep 2
  48. echo -n "."
  49. done
  50. echo ""
  51. log_success "MySQL is online and healthy."
  52. # Step 2: Start local AI Engine (Ollama) and Anonymous Search (SearXNG)
  53. log_info "Step 2/4: Starting Ollama and SearXNG microservices..."
  54. docker compose -f "$COMPOSE_FILE" up -d ollama searxng
  55. # Wait briefly for Ollama daemon bind
  56. sleep 3
  57. log_success "AI and Search infrastructure successfully online."
  58. # Step 3: Start Core Streamlit Application UI and Nginx Gateway Proxy
  59. log_info "Step 3/4: Starting Streamlit UI and Nginx Proxy Gateway..."
  60. docker compose -f "$COMPOSE_FILE" up -d app nginx
  61. log_success "Frontend and Proxy elements online."
  62. # Step 4: Start DevOps Orchestrator Stack (Zabbix Monitoring, Zabbix Agent, Airflow)
  63. log_info "Step 4/4: Deploying Zabbix Monitoring suite and Airflow Supervisors..."
  64. # Note: Airflow scheduler/webserver are started for pipeline supervision
  65. docker compose -f "$COMPOSE_FILE" up -d zabbix-server zabbix-web zabbix-agent
  66. # Check if Airflow service elements exist in compose file before starting
  67. if grep -q "airflow-webserver" "$COMPOSE_FILE"; then
  68. docker compose -f "$COMPOSE_FILE" up -d airflow-webserver airflow-scheduler || log_warn "Airflow containers not defined or failed to start."
  69. fi
  70. log_success "All Local Food AI development services started successfully!"
  71. }
  72. stop_services() {
  73. log_info "Initiating sequential graceful shutdown sequence..."
  74. # Step 1: Stop Monitoring and Supervisor Stack
  75. log_info "Step 1/4: Stopping Zabbix suite and Airflow Supervisors..."
  76. docker compose -f "$COMPOSE_FILE" stop zabbix-agent zabbix-web zabbix-server
  77. if grep -q "airflow-webserver" "$COMPOSE_FILE"; then
  78. docker compose -f "$COMPOSE_FILE" stop airflow-scheduler airflow-webserver || true
  79. fi
  80. log_success "DevOps monitoring stack shut down."
  81. # Step 2: Stop Streamlit Application and Secure Proxy Gateway
  82. log_info "Step 2/4: Shutting down Nginx and App frontend..."
  83. docker compose -f "$COMPOSE_FILE" stop nginx app
  84. log_success "Application frontend shut down."
  85. # Step 3: Stop AI Ollama Inference Engine and SearXNG Search Gateway
  86. log_info "Step 3/4: Stopping SearXNG and Ollama AI Engine..."
  87. docker compose -f "$COMPOSE_FILE" stop searxng ollama
  88. log_success "AI services shut down."
  89. # Step 4: Stop Core MySQL Database Container gracefully (prevent table corruption)
  90. log_info "Step 4/4: Stopping MySQL database..."
  91. docker compose -f "$COMPOSE_FILE" stop mysql
  92. log_success "Database node cleanly shut down."
  93. log_success "All Local Food AI services stopped gracefully!"
  94. }
  95. check_status() {
  96. log_info "Inspecting status of stack containers..."
  97. docker compose -f "$COMPOSE_FILE" ps
  98. log_info "Active network sockets check:"
  99. echo "---------------------------------------------------------"
  100. echo "Port | Target Service | Status"
  101. echo "---------------------------------------------------------"
  102. # Check MySQL on 3307
  103. if nc -z localhost 3307 2>/dev/null; then
  104. echo -e "3307 | MySQL Database Node | ${GREEN}ONLINE${NC}"
  105. else
  106. echo -e "3307 | MySQL Database Node | ${RED}OFFLINE${NC}"
  107. fi
  108. # Check Ollama on 11434
  109. if nc -z localhost 11434 2>/dev/null; then
  110. echo -e "11434 | Ollama AI Engine | ${GREEN}ONLINE${NC}"
  111. else
  112. echo -e "11434 | Ollama AI Engine | ${RED}OFFLINE${NC}"
  113. fi
  114. # Check Nginx Gateway on 80
  115. if nc -z localhost 80 2>/dev/null; then
  116. echo -e "80 | Nginx Gateway (HTTP Proxy) | ${GREEN}ONLINE${NC}"
  117. else
  118. echo -e "80 | Nginx Gateway (HTTP Proxy) | ${RED}OFFLINE${NC}"
  119. fi
  120. # Check Zabbix Web UI on 8081
  121. if nc -z localhost 8081 2>/dev/null; then
  122. echo -e "8081 | Zabbix Dashboard | ${GREEN}ONLINE${NC}"
  123. else
  124. echo -e "8081 | Zabbix Dashboard | ${RED}OFFLINE${NC}"
  125. fi
  126. echo "---------------------------------------------------------"
  127. }
  128. show_help() {
  129. echo "Usage: $0 {start|stop|restart|status}"
  130. echo " start - Deploy and wake up all services sequentially according to priorities."
  131. echo " stop - Gracefully turn off containers in reverse dependency order."
  132. echo " restart - Perform sequential shutdown followed by sequential boot."
  133. echo " status - Print container status and inspect physical TCP port sockets."
  134. exit 1
  135. }
  136. case "$1" in
  137. start)
  138. start_services
  139. ;;
  140. stop)
  141. stop_services
  142. ;;
  143. restart)
  144. stop_services
  145. start_services
  146. ;;
  147. status)
  148. check_status
  149. ;;
  150. *)
  151. show_help
  152. ;;
  153. esac