manage_services.sh 6.7 KB

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