209 lines
5.8 KiB
Bash
209 lines
5.8 KiB
Bash
#!/bin/sh
|
|
set -e
|
|
|
|
# Config
|
|
APP_DIR="${APP_DIR:-/var/www/html}"
|
|
MODULE_DIR="${MODULE_DIR:-$APP_DIR/modules/washcertificates}"
|
|
LOG_FILE="${LOG_FILE:-/var/log/php/composer-install.log}"
|
|
|
|
# Gate auto-install (set to "true" only on one PHP container, e.g. php1)
|
|
AUTO_COMPOSER_INSTALL="${AUTO_COMPOSER_INSTALL:-true}"
|
|
|
|
log() { printf "[entrypoint] %s\n" "$*"; }
|
|
|
|
vendor_sanity_ok() {
|
|
dir="$1"
|
|
autoload_file="$dir/vendor/autoload.php"
|
|
autoload_real_file="$dir/vendor/composer/autoload_real.php"
|
|
aws_s3_api_file="$dir/vendor/aws/aws-sdk-php/src/data/s3/2006-03-01/api-2.json.php"
|
|
|
|
if [ ! -f "$autoload_file" ]; then
|
|
return 1
|
|
fi
|
|
|
|
if [ ! -f "$autoload_real_file" ]; then
|
|
log "Vendor sanity check failed: missing $autoload_real_file"
|
|
return 1
|
|
fi
|
|
|
|
if [ -f "$dir/composer.lock" ] && [ "$dir/composer.lock" -nt "$autoload_file" ]; then
|
|
log "composer.lock is newer than vendor/autoload.php in $dir"
|
|
return 1
|
|
fi
|
|
|
|
if ! php -d display_errors=1 -r 'require $argv[1];' "$autoload_file" >/dev/null 2>&1; then
|
|
log "Vendor sanity check failed for $autoload_file"
|
|
return 1
|
|
fi
|
|
|
|
if ! http_message_sanity_ok "$dir"; then
|
|
return 1
|
|
fi
|
|
|
|
if [ -f "$aws_s3_api_file" ] && ! php -l "$aws_s3_api_file" >/dev/null 2>&1; then
|
|
log "Vendor sanity check failed for $aws_s3_api_file"
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
composer_lock_has_package() {
|
|
dir="$1"
|
|
package="$2"
|
|
|
|
if [ ! -f "$dir/composer.lock" ]; then
|
|
return 1
|
|
fi
|
|
|
|
grep -q "\"name\": \"$package\"" "$dir/composer.lock"
|
|
}
|
|
|
|
http_message_sanity_ok() {
|
|
dir="$1"
|
|
autoload_file="$dir/vendor/autoload.php"
|
|
uri_file="$dir/vendor/psr/http-message/src/UriInterface.php"
|
|
stream_file="$dir/vendor/psr/http-message/src/StreamInterface.php"
|
|
|
|
if ! composer_lock_has_package "$dir" "psr/http-message"; then
|
|
return 0
|
|
fi
|
|
|
|
if [ ! -f "$uri_file" ]; then
|
|
log "Vendor sanity check failed: missing $uri_file"
|
|
return 1
|
|
fi
|
|
|
|
if [ ! -f "$stream_file" ]; then
|
|
log "Vendor sanity check failed: missing $stream_file"
|
|
return 1
|
|
fi
|
|
|
|
if ! php -d display_errors=1 -r 'require $argv[1]; exit(interface_exists("Psr\\Http\\Message\\UriInterface") && interface_exists("Psr\\Http\\Message\\StreamInterface") ? 0 : 1);' "$autoload_file" >/dev/null 2>&1; then
|
|
log "Vendor sanity check failed: psr/http-message interfaces do not autoload in $dir"
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
wait_for_redis() {
|
|
db_target="${CONFIG_DB_TARGET:-live}"
|
|
if [ "$db_target" = "debug" ]; then
|
|
host="${REDIS_CONFIG_DEBUG_HOST:-${REDIS_CONFIG_HOST:-redis}}"
|
|
port="${REDIS_CONFIG_DEBUG_PORT:-${REDIS_CONFIG_PORT:-6379}}"
|
|
pass="${REDIS_CONFIG_DEBUG_PASSWORD:-${REDIS_CONFIG_PASSWORD:-}}"
|
|
else
|
|
host="${REDIS_CONFIG_HOST:-redis}"
|
|
port="${REDIS_CONFIG_PORT:-6379}"
|
|
pass="${REDIS_CONFIG_PASSWORD:-}"
|
|
fi
|
|
timeout="${REDIS_WAIT_TIMEOUT:-60}"
|
|
i=0
|
|
|
|
log "Waiting for Redis at ${host}:${port} (target: ${db_target}, timeout: ${timeout}s) ..."
|
|
while [ "$i" -lt "$timeout" ]; do
|
|
if [ -n "$pass" ]; then
|
|
if redis-cli -h "$host" -p "$port" -a "$pass" PING >/dev/null 2>&1; then
|
|
log "Redis is ready"
|
|
return 0
|
|
fi
|
|
else
|
|
if redis-cli -h "$host" -p "$port" PING >/dev/null 2>&1; then
|
|
log "Redis is ready"
|
|
return 0
|
|
fi
|
|
fi
|
|
sleep 1
|
|
i=$((i+1))
|
|
done
|
|
log "ERROR: Timed out waiting for Redis at ${host}:${port}"
|
|
return 1
|
|
}
|
|
|
|
wait_for_file() {
|
|
target="$1"
|
|
timeout="${2:-120}"
|
|
i=0
|
|
while [ "$i" -lt "$timeout" ]; do
|
|
if [ -e "$target" ]; then
|
|
return 0
|
|
fi
|
|
sleep 1
|
|
i=$((i+1))
|
|
done
|
|
return 1
|
|
}
|
|
|
|
with_install_lock() {
|
|
# Poor-man's lock using a directory
|
|
while ! mkdir /tmp/composer-install.lock 2>/dev/null; do
|
|
sleep 1
|
|
done
|
|
trap 'rmdir /tmp/composer-install.lock 2>/dev/null || true' EXIT HUP INT TERM
|
|
"$@"
|
|
rmdir /tmp/composer-install.lock 2>/dev/null || true
|
|
trap - EXIT HUP INT TERM
|
|
}
|
|
|
|
install_if_needed() {
|
|
dir="$1"
|
|
if [ -f "$dir/composer.json" ]; then
|
|
if ! vendor_sanity_ok "$dir"; then
|
|
if [ -d "$dir/vendor" ]; then
|
|
log "Removing invalid vendor tree in $dir before reinstall"
|
|
rm -rf "$dir/vendor"
|
|
fi
|
|
log "Installing Composer deps in $dir ..."
|
|
mkdir -p "$(dirname "$LOG_FILE")" 2>/dev/null || true
|
|
if ! COMPOSER_ALLOW_SUPERUSER=1 composer install \
|
|
--no-dev --prefer-dist --optimize-autoloader --no-interaction \
|
|
-d "$dir" 2>&1 | tee -a "$LOG_FILE"; then
|
|
log "ERROR: composer install failed in $dir. See $LOG_FILE"
|
|
exit 1
|
|
fi
|
|
if [ ! -f "$dir/vendor/autoload.php" ]; then
|
|
log "ERROR: autoload.php still missing after install in $dir. See $LOG_FILE"
|
|
exit 1
|
|
fi
|
|
chown -R www-data:www-data "$dir/vendor" 2>/dev/null || true
|
|
else
|
|
log "vendor already present and sane in $dir - skipping"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
refresh_root_autoload() {
|
|
if [ -f "$APP_DIR/composer.json" ] && [ -f "$APP_DIR/vendor/autoload.php" ]; then
|
|
log "Refreshing root Composer autoload after module dependency checks ..."
|
|
mkdir -p "$(dirname "$LOG_FILE")" 2>/dev/null || true
|
|
if ! COMPOSER_ALLOW_SUPERUSER=1 composer dump-autoload \
|
|
--optimize --no-interaction \
|
|
-d "$APP_DIR" 2>&1 | tee -a "$LOG_FILE"; then
|
|
log "ERROR: composer dump-autoload failed in $APP_DIR. See $LOG_FILE"
|
|
exit 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
if [ "$AUTO_COMPOSER_INSTALL" = "true" ]; then
|
|
if ! wait_for_file "$APP_DIR/composer.json" 120; then
|
|
log "WARNING: $APP_DIR/composer.json not found after waiting - skipping auto-install"
|
|
else
|
|
with_install_lock install_if_needed "$APP_DIR"
|
|
fi
|
|
|
|
if [ -f "$MODULE_DIR/composer.json" ]; then
|
|
with_install_lock install_if_needed "$MODULE_DIR"
|
|
with_install_lock refresh_root_autoload
|
|
fi
|
|
else
|
|
log "AUTO_COMPOSER_INSTALL=false - skipping Composer auto-install"
|
|
fi
|
|
|
|
if [ -n "${REDIS_CONFIG_HOST:-}" ]; then
|
|
wait_for_redis
|
|
fi
|
|
|
|
exec "$@"
|