#!/usr/bin/env bash set -euo pipefail APP_SOURCE=${APP_SOURCE:-/opt/app} APP_TARGET=${APP_TARGET:-/var/www/html} APP_USER=${APP_USER:-www-data} APP_GROUP=${APP_GROUP:-www-data} SKIP_CODE_SYNC=${SKIP_CODE_SYNC:-0} DB_WAIT_TIMEOUT=${DB_WAIT_TIMEOUT:-60} REDIS_WAIT_TIMEOUT=${REDIS_WAIT_TIMEOUT:-60} sync_code() { if [[ "$SKIP_CODE_SYNC" == "1" ]]; then return fi if [[ ! -d "$APP_TARGET" ]]; then mkdir -p "$APP_TARGET" fi rsync -a --delete --omit-dir-times --no-perms --no-owner --no-group \ --exclude="storage/**" \ --exclude="storage/logs" \ --exclude="storage/framework/sessions" \ "$APP_SOURCE"/ "$APP_TARGET"/ || true chown -R "$APP_USER:$APP_GROUP" "$APP_TARGET" } ensure_helper_scripts() { if compgen -G "$APP_TARGET/scripts/*.sh" > /dev/null; then chmod +x "$APP_TARGET"/scripts/*.sh || true fi } prepare_storage() { cd "$APP_TARGET" if [[ ! -h public/storage ]]; then php artisan storage:link >/dev/null 2>&1 || true fi if [[ -n "${PENDING_MIGRATIONS:-}" ]]; then php artisan migrate --force >/dev/null 2>&1 || true fi } refresh_config_cache() { cd "$APP_TARGET" php artisan config:clear >/dev/null 2>&1 || true php artisan config:cache >/dev/null 2>&1 || true php artisan route:clear >/dev/null 2>&1 || true php artisan view:clear >/dev/null 2>&1 || true } ensure_help_cache() { cd "$APP_TARGET" if [[ "${HELP_SYNC_ON_BOOT:-auto}" == "0" ]]; then return fi if [[ "${HELP_SYNC_ON_BOOT:-auto}" == "1" ]]; then php artisan help:sync >/dev/null 2>&1 || true return fi if ! compgen -G "$APP_TARGET/storage/app/help/*/*/articles.json" > /dev/null; then php artisan help:sync >/dev/null 2>&1 || true fi } wait_for_service() { local name="$1" host="$2" port="$3" timeout="$4" local start start=$(date +%s) echo "[entrypoint] Waiting for ${name} at ${host}:${port} (timeout ${timeout}s)..." while true; do if exec 3<>"/dev/tcp/${host}/${port}" 2>/dev/null; then exec 3>&- 3<&- echo "[entrypoint] ${name} is available." break fi if (( $(date +%s) - start >= timeout )); then echo "[entrypoint] Timeout while waiting for ${name}." >&2 exit 1 fi sleep 2 done } wait_for_dependencies() { local should_wait_db="false" case "${DB_CONNECTION:-sqlite}" in mysql|mariadb) should_wait_db="true" DB_HOST=${DB_HOST:-mysql} DB_PORT=${DB_PORT:-3306} ;; pgsql) should_wait_db="true" DB_HOST=${DB_HOST:-postgres} DB_PORT=${DB_PORT:-5432} ;; esac if [[ "${WAIT_FOR_DB:-$should_wait_db}" == "true" && "$should_wait_db" == "true" ]]; then wait_for_service "database" "$DB_HOST" "$DB_PORT" "$DB_WAIT_TIMEOUT" fi local should_wait_redis="false" if [[ "${QUEUE_CONNECTION:-}" == redis* ]]; then should_wait_redis="true" fi if [[ "${CACHE_DRIVER:-}" == redis ]]; then should_wait_redis="true" fi if [[ "${SESSION_DRIVER:-}" == redis ]]; then should_wait_redis="true" fi if [[ "${FORCE_WAIT_FOR_REDIS:-false}" == "true" ]]; then should_wait_redis="true" fi if [[ "${WAIT_FOR_REDIS:-$should_wait_redis}" == "true" && "$should_wait_redis" == "true" ]]; then wait_for_service "redis" "${REDIS_HOST:-redis}" "${REDIS_PORT:-6379}" "$REDIS_WAIT_TIMEOUT" fi } sync_code ensure_helper_scripts prepare_storage refresh_config_cache wait_for_dependencies ensure_help_cache cd "$APP_TARGET" exec "$@"