#!/bin/bash # --- Color Definitions for Premium Terminal Styling --- GREEN='\033[0;32m' BLUE='\033[0;34m' YELLOW='\033[1;33m' RED='\033[0;31m' CYAN='\033[0;36m' MAGENTA='\033[0;35m' BOLD='\033[1m' NC='\033[0m' # No Color # Helper Functions for Clean Output log_info() { echo -e " ${BLUE}[INFO]${NC} $1" } log_success() { echo -e " ${GREEN}[SUCCESS]${NC} ✔ $1" } log_warning() { echo -e " ${YELLOW}[WARNING]${NC} ⚠ $1" } log_error() { echo -e " ${RED}[ERROR]${NC} ✘ $1" } clear_screen() { clear 2>/dev/null || printf "\033c" } clear_screen # Premium Welcome Header echo -e "${CYAN}======================================================================${NC}" echo -e "${BOLD}${MAGENTA} 🛠️ BIIPROJECT KIT V2 - CORE APPLICATION INSTALLER 🛠️ ${NC}" echo -e "${CYAN}======================================================================${NC}" echo -e " Selamat datang di asisten instalasi otomatis Biiproject Kit." echo -e " Skrip ini akan memvalidasi lingkungan Anda dan menginstal seluruh" echo -e " kebutuhan aplikasi agar siap dijalankan." echo -e "${CYAN}======================================================================${NC}" echo "" # 1. PRE-FLIGHT SYSTEM CHECKS echo -e "${BOLD}${BLUE}[1/7] Memeriksa Kebutuhan Sistem (Pre-flight Checks)...${NC}" # Check Docker Installation if ! command -v docker &> /dev/null; then log_error "Docker tidak ditemukan pada sistem ini." log_warning "Harap instal Docker terlebih dahulu sebelum melanjutkan." exit 1 else log_success "Docker terinstal." fi # Check Docker Daemon Status if ! docker info &> /dev/null; then log_error "Docker daemon tidak berjalan." log_warning "Harap jalankan Docker service Anda (misal: sudo systemctl start docker)." exit 1 else log_success "Docker daemon aktif dan berjalan." fi # Check Docker Compose Installation if ! docker compose version &> /dev/null; then log_warning "Docker Compose v2 tidak terdeteksi. Mencoba memeriksa 'docker-compose' lama..." if ! command -v docker-compose &> /dev/null; then log_error "Docker Compose tidak ditemukan pada sistem." exit 1 else log_success "Docker-compose (v1) terinstal." DOCKER_COMPOSE_CMD="docker-compose" fi else log_success "Docker Compose v2 terinstal." DOCKER_COMPOSE_CMD="docker compose" fi echo "" # 2. ENVIRONMENT CONFIGURATION echo -e "${BOLD}${BLUE}[2/7] Mengonfigurasi File Environment (.env)...${NC}" if [ ! -f .env ]; then if [ -f .env.example ]; then log_info "Membuat file .env baru dari .env.example..." cp .env.example .env log_success "File .env berhasil dibuat." else log_error "File .env.example tidak ditemukan! Tidak dapat membuat file .env." exit 1 fi else log_info "File .env sudah ada. Menggunakan konfigurasi yang ada." fi echo "" # Parse App Port from .env APP_PORT=$(grep "^APP_PORT=" .env | cut -d'=' -f2- | tr -d '"'\''') APP_PORT=${APP_PORT:-8000} # 3. VENDOR & COMPOSER DEPENDENCIES echo -e "${BOLD}${BLUE}[3/7] Menginstal Dependensi PHP (Composer)...${NC}" if [ ! -d vendor ]; then log_info "Direktori 'vendor' tidak ditemukan. Mengunduh dependensi via PHP-Composer container..." 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 --no-interaction --prefer-dist if [ $? -ne 0 ]; then log_error "Gagal menginstal dependensi Composer. Silakan cek koneksi internet Anda." exit 1 fi log_success "Dependensi Composer berhasil diinstal." else log_info "Direktori 'vendor' sudah ada. Melewati instalasi Composer." fi echo "" # 4. SPIN UP DOCKER CONTAINERS echo -e "${BOLD}${BLUE}[4/7] Memulai Container Docker (Database, Redis, Web)...${NC}" log_info "Menjalankan '$DOCKER_COMPOSE_CMD up -d'..." $DOCKER_COMPOSE_CMD up -d if [ $? -ne 0 ]; then log_error "Gagal menjalankan Docker container. Periksa file docker-compose.yml." exit 1 fi log_success "Docker containers berhasil dijalankan." echo "" # Resolve container names dynamically DB_CONTAINER="bii-pgsql" REDIS_CONTAINER="bii-redis" WEB_CONTAINER="laravel.test" # 5. WAITING FOR SERVICES HEALTHY (Postgres & Redis) echo -e "${BOLD}${BLUE}[5/7] Menunggu Database & Redis Siap (Healthcheck)...${NC}" echo -ne " ${YELLOW}Memeriksa PostgreSQL Database ($DB_CONTAINER)...${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}[SELESAI]${NC} ✔ PostgreSQL siap menerima koneksi! " break elif [ "$STATUS" = "unhealthy" ]; then echo -e "\r ${YELLOW}[PERINGATAN]${NC} ⚠ Healthcheck PGSQL melaporkan error. Melanjutkan..." break elif [ -z "$STATUS" ]; then RUNNING=$(docker inspect --format='{{.State.Running}}' "$DB_CONTAINER" 2>/dev/null) if [ "$RUNNING" = "true" ]; then echo -e "\r ${GREEN}[SELESAI]${NC} ✔ PostgreSQL running (tanpa healthcheck status)." break fi fi echo -n "." sleep 1.5 RETRIES=$((RETRIES + 1)) done echo -ne " ${YELLOW}Memeriksa Redis Cache ($REDIS_CONTAINER)...${NC}" RETRIES=0 while [ $RETRIES -lt $MAX_RETRIES ]; do STATUS=$(docker inspect --format='{{.State.Health.Status}}' "$REDIS_CONTAINER" 2>/dev/null) if [ "$STATUS" = "healthy" ]; then echo -e "\r ${GREEN}[SELESAI]${NC} ✔ Redis siap menerima koneksi! " break elif [ "$STATUS" = "unhealthy" ]; then echo -e "\r ${YELLOW}[PERINGATAN]${NC} ⚠ Healthcheck Redis melaporkan error. Melanjutkan..." break elif [ -z "$STATUS" ]; then RUNNING=$(docker inspect --format='{{.State.Running}}' "$REDIS_CONTAINER" 2>/dev/null) if [ "$RUNNING" = "true" ]; then echo -e "\r ${GREEN}[SELESAI]${NC} ✔ Redis running (tanpa healthcheck status)." break fi fi echo -n "." sleep 1.5 RETRIES=$((RETRIES + 1)) done sleep 2 echo "" # 6. INITIALIZING APPLICATION (Key, Database Migrate, NPM) echo -e "${BOLD}${BLUE}[6/7] Menginisialisasi Database & Aset Aplikasi...${NC}" # Secure Permissions First log_info "Mengonfigurasi hak akses file di dalam container..." $DOCKER_COMPOSE_CMD exec -u root laravel.test chown -R sail:sail /var/www/html/storage /var/www/html/bootstrap/cache 2>/dev/null $DOCKER_COMPOSE_CMD exec -u root laravel.test chmod -R 775 /var/www/html/storage /var/www/html/bootstrap/cache 2>/dev/null # Generate 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 log_info "Menghasilkan unique application key..." $DOCKER_COMPOSE_CMD exec -u sail laravel.test php artisan key:generate else log_info "Application key sudah diatur." fi # Migration & Seed log_info "Menjalankan migrasi database dan default seeders..." $DOCKER_COMPOSE_CMD exec -u sail laravel.test php artisan migrate:fresh --seed if [ $? -eq 0 ]; then log_success "Database berhasil di-migrate dan di-seed." else log_error "Gagal melakukan migrasi database." fi # Link Storage log_info "Membuat symbolic link untuk storage..." $DOCKER_COMPOSE_CMD exec -u sail laravel.test php artisan storage:link --quiet 2>/dev/null log_success "Storage link berhasil terhubung." # Install NPM Packages log_info "Memasang dependensi NodeJS (NPM)..." if [ ! -d node_modules ]; then $DOCKER_COMPOSE_CMD exec -u sail laravel.test npm install if [ $? -eq 0 ]; then log_success "Dependensi NodeJS berhasil dipasang." else log_warning "Gagal memasang dependensi NodeJS." fi else log_info "Folder 'node_modules' sudah ada. Melewati instalasi NPM." fi # Build Production Assets log_info "Mengompilasi aset frontend (production build)..." $DOCKER_COMPOSE_CMD exec -u sail laravel.test npm run build if [ $? -eq 0 ]; then log_success "Frontend assets berhasil dikompilasi." else log_warning "Gagal melakukan build frontend assets." fi # Clean up permissions again in case npm install created any root-owned folders $DOCKER_COMPOSE_CMD exec -u root laravel.test chown -R sail:sail /var/www/html/node_modules /var/www/html/package-lock.json 2>/dev/null echo "" # 7. PERMISSIONS & FINISHING echo -e "${BOLD}${BLUE}[7/7] Finishing & Finalizing...${NC}" chmod +x artisan sail run.sh 2>/dev/null log_success "Hak akses berkas lokal (artisan, sail, run.sh) disesuaikan." clear_screen # SUCCESS BOARD echo -e "${GREEN}======================================================================${NC}" echo -e "${BOLD}${GREEN} 🎉 INSTALASI BIIPROJECT KIT BERHASIL DISELESAIKAN! 🎉 ${NC}" echo -e "${GREEN}======================================================================${NC}" echo -e " Aplikasi Anda sekarang siap digunakan!" echo -e "" echo -e " 👉 ${BOLD}URL Aplikasi:${NC} ${CYAN}http://localhost:${APP_PORT}${NC}" echo -e " 👉 ${BOLD}Monitoring Panel:${NC} ${CYAN}http://localhost:${APP_PORT}/system-monitoring${NC}" echo -e " 👉 ${BOLD}Dokumentasi API:${NC} ${CYAN}http://localhost:${APP_PORT}/documentation${NC}" echo -e " 👉 ${BOLD}Layanan Database:${NC} PostgreSQL pada port ${YELLOW}5432${NC}" echo -e " 👉 ${BOLD}Layanan Redis:${NC} Redis pada port ${YELLOW}6379${NC}" echo -e "" echo -e " ========================================================" echo -e " ${BOLD}CARA MENJALANKAN & MENGHENTIKAN APLIKASI:${NC}" echo -e " ========================================================" echo -e " Untuk menjalankan server pengembangan (live reload):" echo -e " ${CYAN}./run.sh${NC}" echo -e "" echo -e " Untuk melihat logs docker secara realtime:" echo -e " ${CYAN}docker compose logs -f${NC}" echo -e "" echo -e " Untuk menghentikan docker container:" echo -e " ${CYAN}docker compose down${NC}" echo -e "${GREEN}======================================================================${NC}" echo ""