build.sh 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  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 and attachments directories if they don't exist
  66. if [ ! -d uploads ]; then
  67. echo "📁 Creating uploads directory..."
  68. mkdir -p uploads
  69. chmod 755 uploads
  70. fi
  71. if [ ! -d attachments ]; then
  72. echo "📁 Creating attachments directory..."
  73. mkdir -p attachments
  74. chmod 755 attachments
  75. fi
  76. # Copy .env to backend/.env.local for PHP application
  77. echo "📝 Copying environment variables to backend/.env.local..."
  78. if [ -f .env ]; then
  79. cp .env backend/.env.local
  80. echo "✅ Environment variables copied to backend/.env.local"
  81. else
  82. echo "❌ .env file not found. Cannot create backend/.env.local"
  83. exit 1
  84. fi
  85. # Check if Redis is already running on the specified port
  86. REDIS_PORT=${REDIS_PORT:-6379}
  87. REDIS_RUNNING=false
  88. REDIS_HOST="localhost"
  89. if command -v netstat &> /dev/null; then
  90. if netstat -tuln 2>/dev/null | grep -q ":$REDIS_PORT "; then
  91. echo "🔴 Redis is already running on port $REDIS_PORT"
  92. REDIS_RUNNING=true
  93. REDIS_HOST=$(netstat -tuln 2>/dev/null | grep ":$REDIS_PORT " | head -1 | awk '{print $4}' | cut -d':' -f1)
  94. if [ "$REDIS_HOST" = "0.0.0.0" ] || [ "$REDIS_HOST" = "::" ]; then
  95. REDIS_HOST="localhost"
  96. fi
  97. fi
  98. elif command -v ss &> /dev/null; then
  99. if ss -tuln 2>/dev/null | grep -q ":$REDIS_PORT "; then
  100. echo "🔴 Redis is already running on port $REDIS_PORT"
  101. REDIS_RUNNING=true
  102. REDIS_HOST=$(ss -tuln 2>/dev/null | grep ":$REDIS_PORT " | head -1 | awk '{print $4}' | cut -d':' -f1)
  103. if [ "$REDIS_HOST" = "0.0.0.0" ] || [ "$REDIS_HOST" = "::" ]; then
  104. REDIS_HOST="localhost"
  105. fi
  106. fi
  107. fi
  108. # Display configuration summary
  109. echo "📋 Configuration Summary:"
  110. echo " 🌐 Frontend Port: ${FRONTEND_PORT:-80}"
  111. echo " 🗄️ Database Host: $DB_HOST"
  112. echo " 🗄️ Database Port: ${DB_PORT:-3306}"
  113. echo " 🗄️ Database Name: ${DB_NAME:-inventory_db}"
  114. echo " 🗄️ Database User: $DB_USER"
  115. echo " 🔴 Redis Port: $REDIS_PORT ($([ "$REDIS_RUNNING" = true ] && echo "EXTERNAL" || echo "DOCKER"))"
  116. echo ""
  117. # Test environment variables and database connectivity
  118. echo "🔍 Testing environment variables and database connectivity..."
  119. echo "ℹ️ Note: If you see Docker Compose threading errors, they can be safely ignored"
  120. if ! timeout 30 docker-compose run --rm inventory-app php /var/www/html/test-env.php 2>/dev/null; then
  121. echo "❌ Environment variables or database connection test failed."
  122. echo "💡 Make sure:"
  123. echo " - Environment variables are properly set in .env"
  124. echo " - Database server is running and accessible"
  125. echo " - Database '$DB_NAME' exists"
  126. echo " - User '$DB_USER' has proper permissions"
  127. echo " - Network allows connection from Docker container"
  128. echo ""
  129. echo "🔍 Debug: Check container logs for detailed error information"
  130. docker-compose logs inventory-app | tail -20 2>/dev/null || echo "Could not fetch logs"
  131. exit 1
  132. fi
  133. # Build and start the application
  134. echo "🔨 Building Docker containers..."
  135. echo "ℹ️ Note: Docker Compose threading errors can be safely ignored during build"
  136. if [ "$REDIS_RUNNING" = true ]; then
  137. echo "🔴 Skipping Redis build (external Redis detected)"
  138. docker-compose build inventory-app 2>/dev/null || docker-compose build inventory-app
  139. else
  140. echo "🔨 Building all containers including Redis..."
  141. docker-compose build 2>/dev/null || docker-compose build
  142. fi
  143. echo "🚀 Starting application..."
  144. if [ "$REDIS_RUNNING" = true ]; then
  145. echo "🔴 Starting application without Redis (using external Redis at $REDIS_HOST:$REDIS_PORT)"
  146. docker-compose up -d inventory-app 2>/dev/null || docker-compose up -d inventory-app
  147. else
  148. echo "🚀 Starting application with Redis..."
  149. docker-compose up -d 2>/dev/null || docker-compose up -d
  150. fi
  151. # Wait a moment for services to start
  152. echo "⏳ Waiting for services to start..."
  153. sleep 10
  154. # Check if containers are running
  155. echo "🔍 Checking container status..."
  156. docker-compose ps 2>/dev/null || echo "⚠️ Could not get container status (Docker Compose threading error)"
  157. # Show logs
  158. echo "📋 Showing application logs..."
  159. docker-compose logs inventory-app 2>/dev/null || echo "⚠️ Could not fetch logs (Docker Compose threading error)"
  160. # Clean up unnecessary Docker images
  161. echo "🧹 Cleaning up unnecessary Docker images..."
  162. echo "🔍 Removing dangling images..."
  163. DANGLING_IMAGES=$(docker images -f "dangling=true" -q)
  164. if [ -n "$DANGLING_IMAGES" ]; then
  165. echo "🗑️ Removing $(echo "$DANGLING_IMAGES" | wc -l) dangling images..."
  166. docker rmi $DANGLING_IMAGES 2>/dev/null || true
  167. else
  168. echo "✅ No dangling images found"
  169. fi
  170. echo "🔍 Removing unused build cache..."
  171. docker builder prune -f --keep-storage 1GB 2>/dev/null || true
  172. echo "🔍 Removing unused images (keeping last 24 hours)..."
  173. # Remove images older than 24 hours that are not being used
  174. 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)
  175. if [ -n "$UNUSED_IMAGES" ]; then
  176. echo "🗑️ Removing old unused images..."
  177. echo "$UNUSED_IMAGES" | xargs docker rmi 2>/dev/null || true
  178. else
  179. echo "✅ No old unused images found"
  180. fi
  181. # Show cleanup results
  182. echo ""
  183. echo "📊 Docker cleanup summary:"
  184. echo " 📦 Images remaining: $(docker images -q | wc -l)"
  185. 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}')"
  186. echo ""
  187. echo "✅ Build complete!"
  188. echo ""
  189. echo "🌐 Application is available at: http://localhost:${FRONTEND_PORT:-80}"
  190. echo "🔧 API endpoints are available at: http://localhost:${FRONTEND_PORT:-80}/api"
  191. echo "🗄️ Connected to database: $DB_HOST:${DB_PORT:-3306}/$DB_NAME"
  192. if [ "$REDIS_RUNNING" = true ]; then
  193. echo "🔴 Using external Redis: $REDIS_HOST:$REDIS_PORT"
  194. else
  195. echo "🔴 Using Docker Redis: localhost:$REDIS_PORT"
  196. fi
  197. echo ""
  198. echo "📝 Management Commands:"
  199. echo " 🛑 Stop application: docker-compose down"
  200. echo " 📋 View logs: docker-compose logs -f"
  201. echo " 🔄 Rebuild: docker-compose build --no-cache"
  202. echo " 🐚 Access container: docker-compose exec inventory-app bash"
  203. echo " 🧹 Full cleanup: docker system prune -a"
  204. if [ "$REDIS_RUNNING" = true ]; then
  205. echo " 🔴 Redis management: Use your external Redis tools"
  206. else
  207. echo " 🔴 Redis access: docker-compose exec redis redis-cli"
  208. fi