#!/bin/bash # --- Color Definitions for Premium Look --- GREEN='\033[0;32m' BLUE='\033[0;34m' YELLOW='\033[1;33m' RED='\033[0;31m' CYAN='\033[0;36m' WHITE='\033[1;37m' BOLD='\033[1m' NC='\033[0m' # No Color echo -e "${CYAN}======================================================${NC}" echo -e "${GREEN}${BOLD} ⚡ Biiproject Kit v2 — Professional Installer ⚡ ${NC}" echo -e "${CYAN}======================================================${NC}" # 1. Pre-flight Checks (Docker & Daemon status) echo -e "${CYAN}[1/7] Verifying Docker environment...${NC}" if ! command -v docker &> /dev/null; then echo -e " ${RED}❌ Error: Docker is not installed on this system.${NC}" echo -e " ${YELLOW}👉 Please install Docker before running the installer.${NC}" exit 1 fi if ! docker info &> /dev/null; then echo -e " ${RED}❌ Error: Docker daemon is not running.${NC}" echo -e " ${YELLOW}👉 Please start Docker Desktop or the Docker service and try again.${NC}" exit 1 fi echo -e " ${GREEN}✔ Docker is installed and running perfectly.${NC}" echo "" # 2. Check and Create Environment File (.env) echo -e "${CYAN}[2/7] Preparing configuration environment (.env)...${NC}" if [ ! -f .env ]; then if [ -f .env.example ]; then cp .env.example .env echo -e " ${GREEN}✔ Created .env from .env.example template.${NC}" else echo -e " ${RED}❌ Error: .env.example template is missing!${NC}" exit 1 fi else echo -e " ${GREEN}✔ Configuration file .env is already present.${NC}" fi echo "" # 3. Clean up conflicting containers echo -e "${CYAN}[3/7] Cleaning up existing container conflicts...${NC}" # Safely stop and remove containers by name to prevent conflict issues on port mapping CONFLICT_CONTAINERS=("bii-kit-web" "bii-kit-pgsql" "bii-kit-redis") for container in "${CONFLICT_CONTAINERS[@]}"; do if [ ! -z "$(docker ps -a -q -f name=^/${container}$ 2>/dev/null)" ]; then echo -ne " ${YELLOW}Removing old container $container...${NC}" docker rm -f "$container" &>/dev/null echo -e "\r ${GREEN}✔ Container $container successfully cleared. ${NC}" fi done echo -e " ${GREEN}✔ Conflict scanning complete.${NC}" echo "" # 4. Zero-Dependency Host Bootstrapping: Composer Install echo -e "${CYAN}[4/7] Installing PHP dependencies via Composer...${NC}" echo -e " ${YELLOW}⚙ Bootstrapping Composer packages inside lightweight PHP container...${NC}" docker run --rm \ -u "$(id -u):$(id -g)" \ -v "$(pwd):/var/www/html" \ -w /var/www/html \ laravelsail/php83-composer:latest \ composer install --ignore-platform-reqs if [ $? -ne 0 ]; then echo -e " ${RED}❌ Error: Composer dependency installation failed.${NC}" exit 1 fi echo -e " ${GREEN}✔ Composer dependencies successfully installed.${NC}" echo "" # 5. Booting Docker Services for DB Migration echo -e "${CYAN}[5/7] Spin up database & Redis services...${NC}" docker compose up pgsql redis -d if [ $? -ne 0 ]; then echo -e " ${RED}❌ Error: Failed to boot Postgres & Redis services.${NC}" exit 1 fi DB_CONTAINER="bii-kit-pgsql" echo -ne " ${YELLOW}Waiting for PostgreSQL ($DB_CONTAINER) to become healthy...${NC}" RETRIES=0 MAX_RETRIES=40 while [ $RETRIES -lt $MAX_RETRIES ]; do STATUS=$(docker inspect --format='{{.State.Health.Status}}' "$DB_CONTAINER" 2>/dev/null) if [ "$STATUS" = "healthy" ]; then echo -e "\r ${GREEN}✔ PostgreSQL is healthy and ready to accept connections! ${NC}" break elif [ "$STATUS" = "unhealthy" ]; then echo -e "\r ${RED}⚠ PostgreSQL health check failed. Proceeding anyway...${NC}" break elif [ -z "$STATUS" ]; then RUNNING=$(docker inspect --format='{{.State.Running}}' "$DB_CONTAINER" 2>/dev/null) if [ "$RUNNING" = "true" ]; then echo -e "\r ${GREEN}✔ PostgreSQL container is running. ${NC}" break fi fi echo -n "." sleep 1.5 RETRIES=$((RETRIES + 1)) done echo "" # 6. Initialize Database & Application Keys echo -e "${CYAN}[6/7] Initializing keys and database seeds...${NC}" # Start sails application container in background temporarily to execute artisan commands docker compose up laravel.test -d # Secure directories owner & permissions echo -e " ${YELLOW}Securing workspace file permissions...${NC}" docker compose exec -u root laravel.test chown -R sail:sail /var/www/html/storage /var/www/html/bootstrap/cache 2>/dev/null docker compose exec -u root laravel.test chmod -R 775 /var/www/html/storage /var/www/html/bootstrap/cache 2>/dev/null # Generate APP_KEY APP_KEY_VAL=$(grep "^APP_KEY=" .env | cut -d'=' -f2- | tr -d '"'\''') if [ -z "$APP_KEY_VAL" ] || [ "$APP_KEY_VAL" = "base64:" ] || [ "$APP_KEY_VAL" = "SomeRandomString" ]; then echo -e " ${YELLOW}⚙ Generating application encryption key...${NC}" docker compose exec -u sail laravel.test php artisan key:generate fi # Run migrations and seeders echo -e " ${YELLOW}⚙ Initializing database schemas & Spatie RBAC tables...${NC}" docker compose exec -u sail laravel.test php artisan migrate:fresh --seed # Generate Passport OAuth2 Keys echo -e " ${YELLOW}⚙ Creating Passport OAuth2 server authentication client keys...${NC}" docker compose exec -u sail laravel.test php artisan passport:keys --force docker compose exec -u sail laravel.test php artisan passport:client --personal --no-interaction echo -e " ${GREEN}✔ Database and keys successfully initialized.${NC}" echo "" # 7. Compiling Frontend assets echo -e "${CYAN}[7/7] Installing and compiling React Frontend...${NC}" echo -e " ${YELLOW}⚙ Installing Node modules (NPM)...${NC}" docker compose exec -u sail laravel.test npm install echo -e " ${YELLOW}⚙ Compiling production web bundles (Vite)...${NC}" docker compose exec -u sail laravel.test npm run build # Storage Symlink docker compose exec -u sail laravel.test php artisan storage:link &>/dev/null # Final permission secure docker compose exec -u root laravel.test chown -R sail:sail /var/www/html/node_modules /var/www/html/package-lock.json 2>/dev/null echo "" echo -e "${CYAN}=================================================================${NC}" echo -e " 🎉 ${GREEN}${BOLD}Installation Complete! biiproject-kit v2 is ready!${NC} 🎉" echo -e "${CYAN}=================================================================${NC}" echo -e " ${WHITE}You can now run the application stack anytime by executing:${NC}" echo -e " 👉 ${GREEN}${BOLD}./run.sh${NC}" echo -e "${CYAN}=================================================================${NC}" echo ""