Sistem untuk admin DUN merekod waktu KTM (Ketua Tempat Mengundi) hadir mengambil peti undi. Data KTM dibaca daripada DB sppm (spr2026) melalui connection kedua — hanya penempatan berjawatan KTM yang dipaparkan. - Dashboard: senarai KTM ikut pusat mengundi (asc) & saluran (asc), status BELUM HADIR (merah) / HADIR (hijau) + tarikh & masa - Carian nama/no. KP, tapisan pusat mengundi & status - Tanda hadir / batal dengan kawalan DUN (admin terhad ke DUN sendiri) - Eksport Excel (worksheet Hadir & Belum Hadir) guna SimpleXlsx - Peranan: superadmin (urus pengguna, semua DUN) & admin DUN - Docker: nginx + php-fpm + queue + scheduler + webhook deploy, port 127.0.0.1:8009, TZ Asia/Kuala_Lumpur di semua container - Zon waktu aplikasi: Asia/Kuala_Lumpur (APP_TIMEZONE) Berasaskan scaffold spr2026_taklimat. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
67 lines
2.1 KiB
Bash
67 lines
2.1 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
cd /var/www/html
|
|
|
|
echo "[entrypoint] Preparing storage directories..."
|
|
mkdir -p \
|
|
storage/app/public \
|
|
storage/framework/cache/data \
|
|
storage/framework/sessions \
|
|
storage/framework/views \
|
|
storage/framework/testing \
|
|
storage/logs \
|
|
bootstrap/cache
|
|
chown -R www-data:www-data storage bootstrap/cache || true
|
|
chmod -R ug+rwX storage bootstrap/cache || true
|
|
|
|
# Refresh package manifest (env vars are available now via compose env_file).
|
|
php artisan package:discover --ansi || true
|
|
|
|
# Wait for the database to be reachable before migrating / caching config.
|
|
wait_for_db() {
|
|
local host="${DB_HOST:-127.0.0.1}"
|
|
local port="${DB_PORT:-3306}"
|
|
echo "[entrypoint] Waiting for database at ${host}:${port}..."
|
|
for i in $(seq 1 30); do
|
|
if php -r '
|
|
$h=getenv("DB_HOST")?:"127.0.0.1";
|
|
$p=getenv("DB_PORT")?:"3306";
|
|
$d=getenv("DB_DATABASE")?:"";
|
|
$u=getenv("DB_USERNAME")?:"root";
|
|
$w=getenv("DB_PASSWORD")?:"";
|
|
try { new PDO("mysql:host=$h;port=$p;dbname=$d", $u, $w, [PDO::ATTR_TIMEOUT=>2]); exit(0); }
|
|
catch (Throwable $e) { exit(1); }
|
|
' >/dev/null 2>&1; then
|
|
echo "[entrypoint] Database is up."
|
|
return 0
|
|
fi
|
|
sleep 2
|
|
done
|
|
echo "[entrypoint] WARNING: database not reachable after timeout; continuing anyway."
|
|
return 0
|
|
}
|
|
|
|
# Cache framework config for performance. Runs in every role so all containers
|
|
# share the same compiled config.
|
|
cache_app() {
|
|
php artisan config:cache --ansi || true
|
|
php artisan route:cache --ansi || true
|
|
php artisan view:cache --ansi || true
|
|
}
|
|
|
|
# Only the primary (web/app) container runs migrations & storage:link, so the
|
|
# queue/scheduler workers don't race on them. Toggle with RUN_MIGRATIONS.
|
|
if [ "${RUN_MIGRATIONS:-true}" = "true" ]; then
|
|
wait_for_db
|
|
cache_app
|
|
echo "[entrypoint] Running migrations..."
|
|
php artisan migrate --force --ansi || echo "[entrypoint] WARNING: migrate failed."
|
|
php artisan storage:link --ansi || true
|
|
else
|
|
cache_app
|
|
fi
|
|
|
|
echo "[entrypoint] Starting: $*"
|
|
exec "$@"
|