Validate and sanitize Composer vendor directory in PHP service's entrypoint script
This commit is contained in:
@@ -11,6 +11,28 @@ AUTO_COMPOSER_INSTALL="${AUTO_COMPOSER_INSTALL:-true}"
|
|||||||
|
|
||||||
log() { printf "[entrypoint] %s\n" "$*"; }
|
log() { printf "[entrypoint] %s\n" "$*"; }
|
||||||
|
|
||||||
|
vendor_sanity_ok() {
|
||||||
|
dir="$1"
|
||||||
|
autoload_file="$dir/vendor/autoload.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 "$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 [ -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
|
||||||
|
}
|
||||||
|
|
||||||
wait_for_redis() {
|
wait_for_redis() {
|
||||||
db_target="${CONFIG_DB_TARGET:-live}"
|
db_target="${CONFIG_DB_TARGET:-live}"
|
||||||
if [ "$db_target" = "debug" ]; then
|
if [ "$db_target" = "debug" ]; then
|
||||||
@@ -38,17 +60,23 @@ wait_for_redis() {
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
sleep 1; i=$((i+1))
|
sleep 1
|
||||||
|
i=$((i+1))
|
||||||
done
|
done
|
||||||
log "ERROR: Timed out waiting for Redis at ${host}:${port}"
|
log "ERROR: Timed out waiting for Redis at ${host}:${port}"
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
wait_for_file() {
|
wait_for_file() {
|
||||||
target="$1"; timeout="${2:-120}"; i=0
|
target="$1"
|
||||||
|
timeout="${2:-120}"
|
||||||
|
i=0
|
||||||
while [ "$i" -lt "$timeout" ]; do
|
while [ "$i" -lt "$timeout" ]; do
|
||||||
if [ -e "$target" ]; then return 0; fi
|
if [ -e "$target" ]; then
|
||||||
sleep 1; i=$((i+1))
|
return 0
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
i=$((i+1))
|
||||||
done
|
done
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
@@ -67,48 +95,44 @@ with_install_lock() {
|
|||||||
install_if_needed() {
|
install_if_needed() {
|
||||||
dir="$1"
|
dir="$1"
|
||||||
if [ -f "$dir/composer.json" ]; then
|
if [ -f "$dir/composer.json" ]; then
|
||||||
if [ ! -f "$dir/vendor/autoload.php" ]; 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 ..."
|
log "Installing Composer deps in $dir ..."
|
||||||
# Ensure log directory exists
|
|
||||||
mkdir -p "$(dirname "$LOG_FILE")" 2>/dev/null || true
|
mkdir -p "$(dirname "$LOG_FILE")" 2>/dev/null || true
|
||||||
# Run install and log output
|
|
||||||
if ! COMPOSER_ALLOW_SUPERUSER=1 composer install \
|
if ! COMPOSER_ALLOW_SUPERUSER=1 composer install \
|
||||||
--no-dev --prefer-dist --optimize-autoloader --no-interaction \
|
--no-dev --prefer-dist --optimize-autoloader --no-interaction \
|
||||||
-d "$dir" 2>&1 | tee -a "$LOG_FILE"; then
|
-d "$dir" 2>&1 | tee -a "$LOG_FILE"; then
|
||||||
log "ERROR: composer install failed in $dir. See $LOG_FILE"
|
log "ERROR: composer install failed in $dir. See $LOG_FILE"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
# Verify autoload was created
|
|
||||||
if [ ! -f "$dir/vendor/autoload.php" ]; then
|
if [ ! -f "$dir/vendor/autoload.php" ]; then
|
||||||
log "ERROR: autoload.php still missing after install in $dir. See $LOG_FILE"
|
log "ERROR: autoload.php still missing after install in $dir. See $LOG_FILE"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
# Best-effort permissions fix (ignore errors on non-Linux filesystems)
|
|
||||||
chown -R www-data:www-data "$dir/vendor" 2>/dev/null || true
|
chown -R www-data:www-data "$dir/vendor" 2>/dev/null || true
|
||||||
else
|
else
|
||||||
log "vendor already present in $dir — skipping"
|
log "vendor already present and sane in $dir - skipping"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Optionally perform auto-install (only on the designated container)
|
|
||||||
if [ "$AUTO_COMPOSER_INSTALL" = "true" ]; then
|
if [ "$AUTO_COMPOSER_INSTALL" = "true" ]; then
|
||||||
# Wait for the bind mount and composer.json to appear (common on Windows/macOS)
|
|
||||||
if ! wait_for_file "$APP_DIR/composer.json" 120; then
|
if ! wait_for_file "$APP_DIR/composer.json" 120; then
|
||||||
log "WARNING: $APP_DIR/composer.json not found after waiting — skipping auto-install"
|
log "WARNING: $APP_DIR/composer.json not found after waiting - skipping auto-install"
|
||||||
else
|
else
|
||||||
with_install_lock install_if_needed "$APP_DIR"
|
with_install_lock install_if_needed "$APP_DIR"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Module (optional)
|
|
||||||
if [ -f "$MODULE_DIR/composer.json" ]; then
|
if [ -f "$MODULE_DIR/composer.json" ]; then
|
||||||
with_install_lock install_if_needed "$MODULE_DIR"
|
with_install_lock install_if_needed "$MODULE_DIR"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
log "AUTO_COMPOSER_INSTALL=false — skipping Composer auto-install"
|
log "AUTO_COMPOSER_INSTALL=false - skipping Composer auto-install"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Wait for Redis before starting PHP-FPM (if host is defined)
|
|
||||||
if [ -n "${REDIS_CONFIG_HOST:-}" ]; then
|
if [ -n "${REDIS_CONFIG_HOST:-}" ]; then
|
||||||
wait_for_redis
|
wait_for_redis
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user