feat: complete install.sh and run.sh scripts with dynamic health check and build assets sync

This commit is contained in:
2026-05-21 21:38:28 +07:00
parent 177160ef03
commit a0673129ee
41 changed files with 507 additions and 310 deletions
+174 -96
View File
@@ -1,169 +1,247 @@
#!/bin/bash
# --- Color Definitions for Premium Look ---
# --- 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'
WHITE='\033[1;37m'
MAGENTA='\033[0;35m'
BOLD='\033[1m'
NC='\033[0m' # No Color
echo -e "${CYAN}======================================================${NC}"
echo -e "${GREEN}${BOLD} 🐳 Biiproject Kit v2 — Docker Runtime Engine 🐳 ${NC}"
echo -e "${CYAN}======================================================${NC}"
# Helper Functions for Clean Output
log_info() {
echo -e " ${BLUE}[INFO]${NC} $1"
}
# 1. Pre-flight Checks
echo -e "${CYAN}[1/6] Checking system environment...${NC}"
if ! command -v docker &> /dev/null; then
echo -e " ${RED}❌ Error: Docker is not installed on this system.${NC}"
exit 1
fi
log_success() {
echo -e " ${GREEN}[SUCCESS]${NC}$1"
}
if ! docker info &> /dev/null; then
echo -e " ${RED}❌ Error: Docker daemon is not running.${NC}"
exit 1
fi
echo -e " ${GREEN}✔ Docker is installed and running perfectly.${NC}"
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 "${BLUE}======================================================================${NC}"
echo -e "${BOLD}${GREEN} 🐳 BIIPROJECT KIT V2 - CONTAINERIZED RUNNER & MONITOR 🐳 ${NC}"
echo -e "${BLUE}======================================================================${NC}"
echo -e " Skrip ini akan memvalidasi port, menyalakan container Docker,"
echo -e " dan mengaktifkan server pengembangan frontend otomatis."
echo -e "${BLUE}======================================================================${NC}"
echo ""
# 2. Port & Container Conflicts Resolution (Self-Healing)
echo -e "${CYAN}[2/6] Preventing port and container name conflicts...${NC}"
# 1. VERIFY INSTALLATION STATE
echo -e "${BOLD}${BLUE}[1/5] Memverifikasi Status Instalasi Aplikasi...${NC}"
# Resolve ports dynamically
PORT_8000=$(grep "^APP_PORT=" .env 2>/dev/null | cut -d'=' -f2- | tr -d '"'\''')
PORT_8000=${PORT_8000:-8000}
# Check for .env file
if [ ! -f .env ]; then
log_warning "File konfigurasi '.env' tidak ditemukan."
log_info "Menjalankan skrip instalasi terlebih dahulu..."
sleep 1.5
if [ -f install.sh ]; then
chmod +x install.sh
./install.sh
exit $?
else
log_error "Skrip install.sh tidak ditemukan!"
exit 1
fi
fi
PORT_5432=$(grep -E "^(FORWARD_DB_PORT|DB_PORT)=" .env 2>/dev/null | head -n1 | cut -d'=' -f2- | tr -d '"'\''')
PORT_5432=${PORT_5432:-5432}
# Check for Composer dependencies
if [ ! -d vendor ] || [ ! -d node_modules ]; then
log_warning "Dependensi aplikasi belum lengkap (vendor atau node_modules hilang)."
log_info "Mengalihkan ke skrip instalasi untuk setup awal..."
sleep 2
if [ -f install.sh ]; then
chmod +x install.sh
./install.sh
exit $?
else
log_error "Skrip install.sh tidak ditemukan!"
exit 1
fi
fi
PORT_6379=$(grep -E "^(FORWARD_REDIS_PORT|REDIS_PORT)=" .env 2>/dev/null | head -n1 | cut -d'=' -f2- | tr -d '"'\''')
PORT_6379=${PORT_6379:-6379}
# Check Docker Installation
if ! command -v docker &> /dev/null; then
log_error "Docker tidak ditemukan pada sistem. Harap instal Docker terlebih dahulu."
exit 1
fi
# Kill local system processes occupying these ports
# Check Docker Daemon
if ! docker info &> /dev/null; then
log_error "Docker daemon tidak aktif. Harap jalankan layanan Docker Anda."
exit 1
fi
# Resolve Docker Compose Command
if docker compose version &> /dev/null; then
DOCKER_COMPOSE_CMD="docker compose"
else
DOCKER_COMPOSE_CMD="docker-compose"
fi
log_success "Sistem siap dijalankan."
echo ""
# 2. RESOLVE PORTS & PREVENT CONFLICTS
echo -e "${BOLD}${BLUE}[2/5] Memeriksa Port Bebas & Konflik Container...${NC}"
# Parse ports from .env
APP_PORT=$(grep "^APP_PORT=" .env | cut -d'=' -f2- | tr -d '"'\''')
APP_PORT=${APP_PORT:-8000}
DB_PORT=$(grep -E "^(FORWARD_DB_PORT|DB_PORT)=" .env | head -n1 | cut -d'=' -f2- | tr -d '"'\''')
DB_PORT=${DB_PORT:-5432}
REDIS_PORT=$(grep -E "^(FORWARD_REDIS_PORT|REDIS_PORT)=" .env | head -n1 | cut -d'=' -f2- | tr -d '"'\''')
REDIS_PORT=${REDIS_PORT:-6379}
# Function to stop conflicting containers on a specific port
stop_conflict_on_port() {
local port=$1
local service_name=$2
local conflicting_container=$(docker ps --filter "publish=$port" --format "{{.Names}}" 2>/dev/null)
if [ ! -z "$conflicting_container" ]; then
# Exclude our own kit containers
if [[ "$conflicting_container" != "bii-web" && "$conflicting_container" != "bii-pgsql" && "$conflicting_container" != "bii-redis" ]]; then
log_warning "Port $port ($service_name) digunakan oleh container '$conflicting_container'."
log_info "Menghentikan container '$conflicting_container' untuk menghindari konflik..."
docker stop "$conflicting_container" &>/dev/null
sleep 1
fi
fi
}
# Stop local processes using fuser/lsof if available
if command -v lsof &>/dev/null && command -v fuser &>/dev/null; then
for port in "$PORT_8000" "$PORT_5432" "$PORT_6379"; do
for port in "$APP_PORT" "$DB_PORT" "$REDIS_PORT"; do
if lsof -Pi :$port -sTCP:LISTEN -t >/dev/null ; then
echo -e " ${YELLOW}⚠ Port $port is occupied locally. Freeing up port $port...${NC}"
log_warning "Port $port digunakan oleh proses lokal. Menghentikan proses..."
fuser -k $port/tcp 2>/dev/null
sleep 1
fi
done
fi
# Scan and remove conflicting stopped containers with same names
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
# Check if container is running
if [ ! -z "$(docker ps -q -f name=^/${container}$ 2>/dev/null)" ]; then
echo -ne " ${YELLOW}Stopping conflicting running container: $container...${NC}"
docker stop "$container" &>/dev/null
fi
echo -ne " ${YELLOW}Removing conflicting container $container to avoid duplication...${NC}"
docker rm -f "$container" &>/dev/null
echo -e "\r ${GREEN}✔ Cleared conflicting container: $container. ${NC}"
fi
done
echo -e " ${GREEN}✔ Environment conflicts resolved successfully.${NC}"
stop_conflict_on_port "$APP_PORT" "Web Aplikasi"
stop_conflict_on_port "$DB_PORT" "Database PostgreSQL"
stop_conflict_on_port "$REDIS_PORT" "Redis Cache"
log_success "Port $APP_PORT (Web), $DB_PORT (DB), dan $REDIS_PORT (Redis) siap digunakan."
echo ""
# 3. Booting Docker Compose Stack
echo -e "${CYAN}[3/6] Starting application containers...${NC}"
docker compose up -d
# 3. START DOCKER CONTAINER STACK
echo -e "${BOLD}${BLUE}[3/5] Mengaktifkan Container Docker (Sail)...${NC}"
$DOCKER_COMPOSE_CMD up -d
if [ $? -ne 0 ]; then
echo -e " ${RED}❌ Error: Failed to start containers. Try running: docker compose down && docker compose up -d${NC}"
log_error "Gagal menyalakan Docker containers."
exit 1
fi
echo -e " ${GREEN}✔ Containers booted successfully.${NC}"
log_success "Docker containers berhasil dinyalakan."
echo ""
# 4. Service Health Check & Permissions Correction
echo -e "${CYAN}[4/6] Waiting for database health & setting permissions...${NC}"
# 4. HEALTH CHECK & PERMISSIONS
echo -e "${BOLD}${BLUE}[4/5] Memvalidasi Kesehatan Layanan & Hak Akses...${NC}"
DB_CONTAINER="bii-kit-pgsql"
REDIS_CONTAINER="bii-kit-redis"
echo -ne " ${YELLOW}Checking PostgreSQL database ($DB_CONTAINER)...${NC}"
# Postgres Check
echo -ne " ${YELLOW}Memeriksa PostgreSQL Database ($DB_CONTAINER)...${NC}"
RETRIES=0
MAX_RETRIES=40
MAX_RETRIES=30
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... ${NC}"
echo -e "\r ${GREEN}[SELESAI]${NC} ✔ PostgreSQL sehat dan siap! "
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 is running (no healthcheck defined). ${NC}"
echo -e "\r ${GREEN}[SELESAI]${NC} ✔ PostgreSQL container aktif. "
break
fi
fi
echo -n "."
sleep 1.5
sleep 1.2
RETRIES=$((RETRIES + 1))
done
echo -ne " ${YELLOW}Checking Redis cache ($REDIS_CONTAINER)...${NC}"
# Redis Check
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}✔ Redis is healthy and ready! ${NC}"
echo -e "\r ${GREEN}[SELESAI]${NC} ✔ Redis sehat dan siap! "
break
elif [ -z "$STATUS" ]; then
RUNNING=$(docker inspect --format='{{.State.Running}}' "$REDIS_CONTAINER" 2>/dev/null)
if [ "$RUNNING" = "true" ]; then
echo -e "\r ${GREEN}✔ Redis is running. ${NC}"
echo -e "\r ${GREEN}[SELESAI]${NC} ✔ Redis container aktif. "
break
fi
fi
echo -n "."
sleep 1.5
sleep 1.2
RETRIES=$((RETRIES + 1))
done
# Extra sleep for container initialization
sleep 2
# Writable directories permission fix
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
echo -e " ${GREEN}✔ Folder write permissions secured.${NC}"
# Secure storage and cache permissions inside 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
log_success "Hak akses file storage & cache berhasil diselaraskan."
echo ""
# 5. Database Migration Sync
echo -e "${CYAN}[5/6] Checking for pending database migrations...${NC}"
docker compose exec -u sail laravel.test php artisan migrate
# 5. START VITE FRONTEND LIVE SERVER
echo -e "${BOLD}${BLUE}[5/5] Memulai Server Frontend (Vite Live-Reload)...${NC}"
# Start npm dev in background inside container
$DOCKER_COMPOSE_CMD exec -d -u sail laravel.test npm run dev
log_success "Server pengembangan Vite aktif di latar belakang."
echo ""
# 6. Booting Live-reload Dev Server
echo -e "${CYAN}[6/6] Launching React Vite dev server...${NC}"
# Stop any duplicate background dev servers inside container
docker compose exec -u sail laravel.test pkill -f "vite" &>/dev/null
sleep 1
clear_screen
# Start Vite server in detached mode
docker compose exec -d -u sail laravel.test npm run dev
echo -e " ${GREEN}✔ Vite live-reload dev server launched in background.${NC}"
echo ""
# Final Premium Screen Info
echo -e "${CYAN}=========================================================${NC}"
echo -e " 🎉 ${GREEN}${BOLD}Biiproject Kit v2 is running successfully!${NC} 🎉"
echo -e "${CYAN}=========================================================${NC}"
echo -e " 🚀 ${WHITE}${BOLD}Web Application:${NC} ${GREEN}http://localhost:${PORT_8000}${NC}"
echo -e " 📋 ${WHITE}${BOLD}Activity Telemetry:${NC} ${GREEN}http://localhost:${PORT_8000}/activity-logs${NC}"
echo -e " 📖 ${WHITE}${BOLD}Documentation Hub:${NC} ${GREEN}http://localhost:${PORT_8000}/documentation${NC}"
echo -e " 🐘 ${WHITE}${BOLD}Postgres Port:${NC} ${YELLOW}${PORT_5432}${NC}"
echo -e " 🍒 ${WHITE}${BOLD}Redis Port:${NC} ${YELLOW}${PORT_6379}${NC}"
echo -e "${CYAN}=========================================================${NC}"
echo -e " ${YELLOW}${BOLD}Useful Commands:${NC}"
echo -e " 👉 View live logs: ${CYAN}docker compose logs -f${NC}"
echo -e " 👉 Stop the stack: ${CYAN}docker compose down${NC}"
echo -e " 👉 Restart containers: ${CYAN}./run.sh${NC}"
echo -e "${CYAN}=========================================================${NC}"
# Premium Dashboard Information Board
echo -e "${GREEN}======================================================================${NC}"
echo -e "${BOLD}${GREEN} 🚀 BIIPROJECT KIT V2 BERHASIL DIJALANKAN! 🚀 ${NC}"
echo -e "${GREEN}======================================================================${NC}"
echo -e " Aplikasi Anda berjalan lancar di dalam Docker container."
echo -e ""
echo -e " 👉 ${BOLD}Web Application:${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}Database Port:${NC} ${YELLOW}${DB_PORT}${NC} (PostgreSQL)"
echo -e " 👉 ${BOLD}Redis Port:${NC} ${YELLOW}${REDIS_PORT}${NC} (Redis)"
echo -e ""
echo -e " ========================================================"
echo -e " ${BOLD}PERINTAH BERMANFAAT LAINNYA:${NC}"
echo -e " ========================================================"
echo -e " Untuk melihat logs realtime dari container:"
echo -e " ${CYAN}docker compose logs -f${NC}"
echo -e ""
echo -e " Untuk masuk ke terminal container aplikasi:"
echo -e " ${CYAN}./sail shell${NC}"
echo -e ""
echo -e " Untuk menghentikan dan menonaktifkan container:"
echo -e " ${CYAN}docker compose down${NC}"
echo -e "${GREEN}======================================================================${NC}"
echo ""