#!/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 "$@"