1
0

setup_deploy.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. import os
  2. import sys
  3. import getpass
  4. import subprocess
  5. def clear_screen():
  6. os.system('cls' if os.name == 'nt' else 'clear')
  7. print("="*60)
  8. print(" Local Food AI - Distributed Deployment Configuration Tool")
  9. print("="*60)
  10. # Check Docker availability
  11. try:
  12. subprocess.run(["docker", "info"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True)
  13. print("[+] Docker is correctly configured and accessible.")
  14. except (subprocess.CalledProcessError, FileNotFoundError):
  15. print("[-] Warning: Docker is not running or not accessible. Please ensure Docker Desktop or Docker Engine is installed and running before deploying.")
  16. print("\nSelect the role for this specific node in the network:")
  17. print("1. All-in-One (Runs everything, default)")
  18. print("2. Application Frontend (Runs Streamlit, Nginx, AI Services)")
  19. print("3. Database Node (Runs MySQL & Ingestion)")
  20. print("4. Monitoring Node (Runs Zabbix Server & UI)")
  21. choice = input("\nEnter choice (1-4) [1]: ").strip() or "1"
  22. # Environment Variables
  23. env_vars = {}
  24. if choice != "1":
  25. print("\n--- Network Configuration ---")
  26. if choice != "3":
  27. env_vars['DB_HOST'] = input("Enter the IP address of the Database Node: ").strip()
  28. else:
  29. env_vars['DB_HOST'] = "mysql"
  30. if choice != "4":
  31. env_vars['ZBX_SERVER_HOST'] = input("Enter the IP address of the Monitoring Node: ").strip()
  32. else:
  33. env_vars['ZBX_SERVER_HOST'] = "zabbix-server"
  34. else:
  35. env_vars['DB_HOST'] = "mysql"
  36. env_vars['ZBX_SERVER_HOST'] = "zabbix-server"
  37. print("\n--- Security Configuration ---")
  38. env_vars['MYSQL_ROOT_PASSWORD'] = getpass.getpass("Enter MySQL Root Password (will not echo): ")
  39. env_vars['DB_READER_PASS'] = getpass.getpass("Enter DB Reader Password: ")
  40. env_vars['DB_LOADER_PASS'] = getpass.getpass("Enter DB Loader Password: ")
  41. env_vars['DB_APP_AUTH_PASS'] = getpass.getpass("Enter App Auth Password: ")
  42. env_vars['MYSQL_ZABBIX_PASSWORD'] = getpass.getpass("Enter Zabbix DB Password: ")
  43. # Generate .env
  44. print("\n[+] Generating .env file...")
  45. with open(".env", "w") as f:
  46. for k, v in env_vars.items():
  47. f.write(f"{k}={v}\n")
  48. # Base compose dictionaries
  49. compose_services = {}
  50. mysql_service = """
  51. mysql:
  52. build:
  53. context: ./docker/mysql
  54. ports:
  55. - "3307:3306"
  56. volumes:
  57. - mysql_data:/var/lib/mysql
  58. - ./my.cnf:/etc/mysql/conf.d/custom_ai_app.cnf
  59. - ./init.sql:/docker-entrypoint-initdb.d/1-init.sql
  60. environment:
  61. - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
  62. healthcheck:
  63. test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
  64. interval: 10s
  65. timeout: 5s
  66. retries: 20
  67. restart: always
  68. """
  69. ingest_service = """
  70. ingest:
  71. build:
  72. context: .
  73. dockerfile: docker/ingest/Dockerfile
  74. environment:
  75. - DB_HOST=${DB_HOST}
  76. - DB_USER=food_loader
  77. - DB_PASS=${DB_LOADER_PASS}
  78. volumes:
  79. - ./:/app
  80. profiles:
  81. - manual
  82. """
  83. ai_services = """
  84. ollama:
  85. image: ollama/ollama:latest
  86. volumes:
  87. - ollama_data:/root/.ollama
  88. restart: always
  89. searxng:
  90. image: searxng/searxng:latest
  91. ports:
  92. - "8080:8080"
  93. volumes:
  94. - ./searxng:/etc/searxng
  95. environment:
  96. - SEARXNG_BASE_URL=http://localhost:8080/
  97. restart: always
  98. """
  99. app_service = """
  100. app:
  101. build:
  102. context: .
  103. dockerfile: docker/app/Dockerfile
  104. ports:
  105. - "8502:8501"
  106. environment:
  107. - DB_HOST=${DB_HOST}
  108. - DB_USER=food_reader
  109. - DB_PASS=${DB_READER_PASS}
  110. - APP_AUTH_USER=food_app_auth
  111. - APP_AUTH_PASS=${DB_APP_AUTH_PASS}
  112. - OLLAMA_HOST=http://ollama:11434
  113. - SEARXNG_HOST=http://searxng:8080
  114. restart: always
  115. nginx:
  116. image: nginx:latest
  117. ports:
  118. - "80:80"
  119. volumes:
  120. - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
  121. restart: always
  122. """
  123. monitoring_services = """
  124. zabbix-server:
  125. image: zabbix/zabbix-server-mysql:ubuntu-7.0-latest
  126. environment:
  127. - DB_SERVER_HOST=${DB_HOST}
  128. - MYSQL_USER=zabbix
  129. - MYSQL_PASSWORD=${MYSQL_ZABBIX_PASSWORD}
  130. - ZBX_SNMPTRAPPER=1
  131. restart: always
  132. ports:
  133. - "10051:10051"
  134. zabbix-web:
  135. image: zabbix/zabbix-web-nginx-mysql:ubuntu-7.0-latest
  136. ports:
  137. - "8081:8080"
  138. - "8444:8443"
  139. environment:
  140. - DB_SERVER_HOST=${DB_HOST}
  141. - MYSQL_USER=zabbix
  142. - MYSQL_PASSWORD=${MYSQL_ZABBIX_PASSWORD}
  143. - ZBX_SERVER_HOST=zabbix-server
  144. - PHP_TZ=Europe/Paris
  145. restart: always
  146. zabbix-agent:
  147. image: zabbix/zabbix-agent:ubuntu-7.0-latest
  148. environment:
  149. - ZBX_HOSTNAME=DistributedNode
  150. - ZBX_SERVER_HOST=${ZBX_SERVER_HOST}
  151. privileged: true
  152. pid: "host"
  153. volumes:
  154. - /var/run:/var/run
  155. restart: always
  156. """
  157. header = "services:\n"
  158. footer = """
  159. volumes:
  160. mysql_data:
  161. ollama_data:
  162. """
  163. compose_content = header
  164. if choice == "1":
  165. compose_content += mysql_service + ingest_service + ai_services + app_service + monitoring_services
  166. elif choice == "2":
  167. compose_content += ai_services + app_service
  168. footer = "volumes:\n ollama_data:\n"
  169. elif choice == "3":
  170. compose_content += mysql_service + ingest_service
  171. footer = "volumes:\n mysql_data:\n"
  172. elif choice == "4":
  173. compose_content += monitoring_services
  174. footer = ""
  175. print("\n[+] Generating docker-compose.yml for selected role...")
  176. with open("docker-compose.yml", "w") as f:
  177. f.write(compose_content + footer)
  178. print("\n" + "="*60)
  179. print("⚠️ IMPORTANT HYPERVISOR NETWORKING REMINDER:")
  180. print("If this node is running inside VirtualBox or Hyper-V, you MUST configure the VM network adapter to use a 'Bridged Adapter' or 'External Virtual Switch' so it shares the host's subnet. Otherwise, cross-node communication will fail.")
  181. print("="*60)
  182. print("\nDone! You can now run `docker compose up -d`.")