#!/bin/sh # ────────────────────────────────────────────────────────────────────────────── # KOIPB MAT — Container Entrypoint # Jalankan sebelum php-fpm bermula: # 1. Install Composer deps (jika vendor tiada) # 2. Tunggu MySQL # 3. Generate APP_KEY jika tiada # 4. Migrate + seed peranan/pengguna (idempotent) # 5. Storage link + permissions # 6. Cache (prod sahaja) # ────────────────────────────────────────────────────────────────────────────── set -e echo "" echo "╔════════════════════════════════════════╗" echo "║ KOIPB MAT — Container Start ║" echo "╚════════════════════════════════════════╝" echo "" # ── 1. Pasang Composer dependencies ─────────────────────────────────────────── if [ ! -d /var/www/html/vendor ]; then echo "📦 Memasang Composer dependencies..." if [ "${APP_ENV}" = "production" ]; then composer install --no-interaction --no-dev --no-progress --prefer-dist --optimize-autoloader else composer install --no-interaction --no-progress --prefer-dist fi fi # ── 2. Tunggu MySQL bersedia ────────────────────────────────────────────────── DB_HOST="${DB_HOST:-mysql}" DB_PORT="${DB_PORT:-3306}" DB_DATABASE="${DB_DATABASE:-koipb_mat}" DB_USERNAME="${DB_USERNAME:-koipb}" DB_PASSWORD="${DB_PASSWORD:-secret}" echo "⏳ Menunggu MySQL di ${DB_HOST}:${DB_PORT}..." until php -r " try { new PDO('mysql:host=${DB_HOST};port=${DB_PORT};dbname=${DB_DATABASE}', '${DB_USERNAME}', '${DB_PASSWORD}'); exit(0); } catch (Exception \$e) { exit(1); } " 2>/dev/null; do printf "." sleep 2 done echo "" echo "✓ MySQL bersedia." # ── 2b. Fix storage permissions ─────────────────────────────────────────────── mkdir -p /var/www/html/storage/framework/views \ /var/www/html/storage/framework/cache/data \ /var/www/html/storage/framework/sessions \ /var/www/html/storage/logs \ /var/www/html/storage/app/public \ /var/www/html/bootstrap/cache chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache 2>/dev/null || true chmod -R 775 /var/www/html/storage /var/www/html/bootstrap/cache 2>/dev/null || true # ── 3. Generate APP_KEY jika kosong ─────────────────────────────────────────── # Fail .env dalam container = .env.docker (di-overlay melalui volume). if [ -z "${APP_KEY}" ]; then echo "🔑 Menjana APP_KEY..." php artisan key:generate --force fi # env_file menyuntik APP_KEY (mungkin kosong) sebagai env var sebenar yang # mengatasi nilai dalam fail. Baca semula dari .env & EXPORT supaya proses anak # (migrate, config:cache, php-fpm) mewarisi kunci yang betul. if [ -f /var/www/html/.env ]; then FILE_KEY=$(grep -E '^APP_KEY=' /var/www/html/.env | head -1 | cut -d= -f2-) [ -n "${FILE_KEY}" ] && export APP_KEY="${FILE_KEY}" fi # ── 3b. Bersihkan cache lama ────────────────────────────────────────────────── # Penting: config.php basi (cth dari deploy lama) boleh mengatasi .env semasa. php artisan config:clear 2>/dev/null || true php artisan route:clear 2>/dev/null || true php artisan view:clear 2>/dev/null || true # ── 4. Migration + seed peranan & pengguna (idempotent) ─────────────────────── echo "🗄 Menjalankan migration..." php artisan migrate --force echo "👤 Seeding peranan & pengguna (RoleUserSeeder)..." php artisan db:seed --class=RoleUserSeeder --force # Seed data demo (200 anggota + 21 hadiah) hanya bila SEED_DEMO=true if [ "${SEED_DEMO}" = "true" ]; then echo "🎁 Seeding data demo penuh (DatabaseSeeder)..." php artisan db:seed --force fi # ── 5. Storage symbolic link ────────────────────────────────────────────────── php artisan storage:link 2>/dev/null || true # ── 6. Cache (production sahaja) ────────────────────────────────────────────── if [ "${APP_ENV}" = "production" ]; then echo "⚡ Caching config, routes, views..." php artisan config:cache php artisan route:cache php artisan view:cache else php artisan optimize:clear 2>/dev/null || true fi echo "" echo "✅ Aplikasi bersedia." echo "" exec "$@"