build.sh 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. #!/bin/bash
  2. # Inventory Management System Docker Build Script
  3. # This script builds and deploys the complete inventory solution
  4. set -e
  5. echo "🚀 Building Inventory Management System..."
  6. # Docker Compose wrapper function to handle threading errors
  7. docker_compose_safe() {
  8. local max_attempts=3
  9. local attempt=1
  10. local cmd="$@"
  11. while [ $attempt -le $max_attempts ]; do
  12. echo "🔄 Docker Compose attempt $attempt/$max_attempts: $cmd"
  13. if docker-compose $cmd 2>/dev/null; then
  14. echo "✅ Docker Compose command succeeded"
  15. return 0
  16. else
  17. echo "⚠️ Docker Compose command failed (attempt $attempt/$max_attempts)"
  18. if [ $attempt -eq $max_attempts ]; then
  19. echo "🔧 Trying without stderr redirection..."
  20. if docker-compose $cmd; then
  21. echo "✅ Docker Compose command succeeded on retry"
  22. return 0
  23. else
  24. echo "❌ Docker Compose command failed after $max_attempts attempts"
  25. return 1
  26. fi
  27. fi
  28. sleep 2
  29. ((attempt++))
  30. fi
  31. done
  32. return 1
  33. }
  34. # Load environment variables from .env file
  35. if [ -f .env ]; then
  36. echo "📝 Loading environment variables from .env..."
  37. export $(cat .env | grep -v '^#' | xargs)
  38. else
  39. echo "❌ .env file not found. Please copy .env.example to .env and configure it."
  40. exit 1
  41. fi
  42. # Check if Docker is installed
  43. if ! command -v docker &> /dev/null; then
  44. echo "❌ Docker is not installed. Please install Docker first."
  45. exit 1
  46. fi
  47. # Check if Docker Compose is installed
  48. if ! command -v docker-compose &> /dev/null; then
  49. echo "❌ Docker Compose is not installed. Please install Docker Compose first."
  50. exit 1
  51. fi
  52. # Validate required environment variables
  53. if [ -z "$DB_HOST" ] || [ "$DB_HOST" = "your-external-db-host" ]; then
  54. echo "❌ DB_HOST is not configured in .env. Please set your external database host."
  55. exit 1
  56. fi
  57. if [ -z "$DB_USER" ] || [ "$DB_USER" = "your-db-username" ]; then
  58. echo "❌ DB_USER is not configured in .env. Please set your database username."
  59. exit 1
  60. fi
  61. if [ -z "$DB_PASS" ] || [ "$DB_PASS" = "your-db-password" ]; then
  62. echo "❌ DB_PASS is not configured in .env. Please set your database password."
  63. exit 1
  64. fi
  65. # Create uploads directory if it doesn't exist
  66. if [ ! -d uploads ]; then
  67. echo "📁 Creating uploads directory..."
  68. mkdir -p uploads
  69. chmod 755 uploads
  70. fi
  71. # Copy .env to backend/.env.local for PHP application
  72. echo "📝 Copying environment variables to backend/.env.local..."
  73. if [ -f .env ]; then
  74. cp .env backend/.env.local
  75. echo "✅ Environment variables copied to backend/.env.local"
  76. else
  77. echo "❌ .env file not found. Cannot create backend/.env.local"
  78. exit 1
  79. fi
  80. # Check if Redis is already running on the specified port
  81. REDIS_PORT=${REDIS_PORT:-6379}
  82. REDIS_RUNNING=false
  83. REDIS_HOST="localhost"
  84. if command -v netstat &> /dev/null; then
  85. if netstat -tuln 2>/dev/null | grep -q ":$REDIS_PORT "; then
  86. echo "🔴 Redis is already running on port $REDIS_PORT"
  87. REDIS_RUNNING=true
  88. REDIS_HOST=$(netstat -tuln 2>/dev/null | grep ":$REDIS_PORT " | head -1 | awk '{print $4}' | cut -d':' -f1)
  89. if [ "$REDIS_HOST" = "0.0.0.0" ] || [ "$REDIS_HOST" = "::" ]; then
  90. REDIS_HOST="localhost"
  91. fi
  92. fi
  93. elif command -v ss &> /dev/null; then
  94. if ss -tuln 2>/dev/null | grep -q ":$REDIS_PORT "; then
  95. echo "🔴 Redis is already running on port $REDIS_PORT"
  96. REDIS_RUNNING=true
  97. REDIS_HOST=$(ss -tuln 2>/dev/null | grep ":$REDIS_PORT " | head -1 | awk '{print $4}' | cut -d':' -f1)
  98. if [ "$REDIS_HOST" = "0.0.0.0" ] || [ "$REDIS_HOST" = "::" ]; then
  99. REDIS_HOST="localhost"
  100. fi
  101. fi
  102. fi
  103. # Display configuration summary
  104. echo "📋 Configuration Summary:"
  105. echo " 🌐 Frontend Port: ${FRONTEND_PORT:-80}"
  106. echo " 🗄️ Database Host: $DB_HOST"
  107. echo " 🗄️ Database Port: ${DB_PORT:-3306}"
  108. echo " 🗄️ Database Name: ${DB_NAME:-inventory_db}"
  109. echo " 🗄️ Database User: $DB_USER"
  110. echo " 🔴 Redis Port: $REDIS_PORT ($([ "$REDIS_RUNNING" = true ] && echo "EXTERNAL" || echo "DOCKER"))"
  111. echo ""
  112. # Test environment variables and database connectivity
  113. echo "🔍 Testing environment variables and database connectivity..."
  114. echo "ℹ️ Note: If you see Docker Compose threading errors, they can be safely ignored"
  115. if ! timeout 30 docker-compose run --rm inventory-app php /var/www/html/test-env.php 2>/dev/null; then
  116. echo "❌ Environment variables or database connection test failed."
  117. echo "💡 Make sure:"
  118. echo " - Environment variables are properly set in .env"
  119. echo " - Database server is running and accessible"
  120. echo " - Database '$DB_NAME' exists"
  121. echo " - User '$DB_USER' has proper permissions"
  122. echo " - Network allows connection from Docker container"
  123. echo ""
  124. echo "🔍 Debug: Check container logs for detailed error information"
  125. docker-compose logs inventory-app | tail -20 2>/dev/null || echo "Could not fetch logs"
  126. exit 1
  127. fi
  128. # Build and start the application
  129. echo "🔨 Building Docker containers..."
  130. echo "ℹ️ Note: Docker Compose threading errors can be safely ignored during build"
  131. if [ "$REDIS_RUNNING" = true ]; then
  132. echo "🔴 Skipping Redis build (external Redis detected)"
  133. docker-compose build inventory-app 2>/dev/null || docker-compose build inventory-app
  134. else
  135. echo "🔨 Building all containers including Redis..."
  136. docker-compose build 2>/dev/null || docker-compose build
  137. fi
  138. echo "🚀 Starting application..."
  139. if [ "$REDIS_RUNNING" = true ]; then
  140. echo "🔴 Starting application without Redis (using external Redis at $REDIS_HOST:$REDIS_PORT)"
  141. docker-compose up -d inventory-app 2>/dev/null || docker-compose up -d inventory-app
  142. else
  143. echo "🚀 Starting application with Redis..."
  144. docker-compose up -d 2>/dev/null || docker-compose up -d
  145. fi
  146. # Wait a moment for services to start
  147. echo "⏳ Waiting for services to start..."
  148. sleep 10
  149. # Check if containers are running
  150. echo "🔍 Checking container status..."
  151. docker-compose ps 2>/dev/null || echo "⚠️ Could not get container status (Docker Compose threading error)"
  152. # Show logs
  153. echo "📋 Showing application logs..."
  154. docker-compose logs inventory-app 2>/dev/null || echo "⚠️ Could not fetch logs (Docker Compose threading error)"
  155. # Clean up unnecessary Docker images
  156. echo "🧹 Cleaning up unnecessary Docker images..."
  157. echo "🔍 Removing dangling images..."
  158. DANGLING_IMAGES=$(docker images -f "dangling=true" -q)
  159. if [ -n "$DANGLING_IMAGES" ]; then
  160. echo "🗑️ Removing $(echo "$DANGLING_IMAGES" | wc -l) dangling images..."
  161. docker rmi $DANGLING_IMAGES 2>/dev/null || true
  162. else
  163. echo "✅ No dangling images found"
  164. fi
  165. echo "🔍 Removing unused build cache..."
  166. docker builder prune -f --keep-storage 1GB 2>/dev/null || true
  167. echo "🔍 Removing unused images (keeping last 24 hours)..."
  168. # Remove images older than 24 hours that are not being used
  169. UNUSED_IMAGES=$(docker images --format "table {{.Repository}}:{{.Tag}}\t{{.CreatedAt}}\t{{.ID}}" | grep -v "REPOSITORY" | awk '$2 < "'$(date -d '24 hours ago' '+%Y-%m-%d %H:%M:%S')'" {print $3}' | head -10)
  170. if [ -n "$UNUSED_IMAGES" ]; then
  171. echo "🗑️ Removing old unused images..."
  172. echo "$UNUSED_IMAGES" | xargs docker rmi 2>/dev/null || true
  173. else
  174. echo "✅ No old unused images found"
  175. fi
  176. # Show cleanup results
  177. echo ""
  178. echo "📊 Docker cleanup summary:"
  179. echo " 📦 Images remaining: $(docker images -q | wc -l)"
  180. echo " 💾 Space used: $(docker system df --format "table {{.Type}}\t{{.TotalCount}}\t{{.Size}}" | grep -E "Images|Local Volumes" | awk '{printf " %-15s %3s %10s\n", $1, $2, $3}')"
  181. echo ""
  182. echo "✅ Build complete!"
  183. echo ""
  184. echo "🌐 Application is available at: http://localhost:${FRONTEND_PORT:-80}"
  185. echo "🔧 API endpoints are available at: http://localhost:${FRONTEND_PORT:-80}/api"
  186. echo "🗄️ Connected to database: $DB_HOST:${DB_PORT:-3306}/$DB_NAME"
  187. if [ "$REDIS_RUNNING" = true ]; then
  188. echo "🔴 Using external Redis: $REDIS_HOST:$REDIS_PORT"
  189. else
  190. echo "🔴 Using Docker Redis: localhost:$REDIS_PORT"
  191. fi
  192. echo ""
  193. echo "📝 Management Commands:"
  194. echo " 🛑 Stop application: docker-compose down"
  195. echo " 📋 View logs: docker-compose logs -f"
  196. echo " 🔄 Rebuild: docker-compose build --no-cache"
  197. echo " 🐚 Access container: docker-compose exec inventory-app bash"
  198. echo " 🧹 Full cleanup: docker system prune -a"
  199. if [ "$REDIS_RUNNING" = true ]; then
  200. echo " 🔴 Redis management: Use your external Redis tools"
  201. else
  202. echo " 🔴 Redis access: docker-compose exec redis redis-cli"
  203. fi