#!/bin/bash set -e # Function to log with timestamp and prefix log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] [ENTRYPOINT] $1" >&2 } # Log directly to stderr (will show in Docker logs) log "Starting entrypoint script..." # Check if DWG_FOLDER exists and has correct permissions DWG_FOLDER="/app/dwg_files" DB_FOLDER="/app/database_files" if [ ! -d "$DWG_FOLDER" ]; then log "⚠️ Creating $DWG_FOLDER directory..." mkdir -p "$DWG_FOLDER" fi if [ ! -d "$DB_FOLDER" ]; then log "⚠️ Creating $DB_FOLDER directory..." mkdir -p "$DB_FOLDER" fi # Print mount information for debugging log "📁 Checking mount points..." mount | grep "$DWG_FOLDER" || log "No specific mount for $DWG_FOLDER found" mount | grep "$DB_FOLDER" || log "No specific mount for $DB_FOLDER found" log "📁 Directory permissions:" ls -la "$DWG_FOLDER" | while read line; do log "$line"; done ls -la "$DB_FOLDER" | while read line; do log "$line"; done # log "📂 Generating initial manifest..." # python /app/generate_manifest.py 2>&1 | while read line; do log "[MANIFEST] $line"; done # Function to handle file watching watch_files() { local timestamp_file="/tmp/last_event_time" local debounce_delay=3 # Wait 3 seconds for more events local regeneration_lock="/tmp/regenerating_manifest" # Initialize timestamp file echo "0" > "$timestamp_file" while true; do log "👀 Watching $DWG_FOLDER and $DB_FOLDER for changes..." log "💡 Using recursive monitoring with all events..." # Add more event types and increase the inotify watches limit echo fs.inotify.max_user_watches=524288 | tee -a /etc/sysctl.conf && sysctl -p >/dev/null 2>&1 || true # Monitor more events including those that might occur on bind mounts inotifywait -m -r \ -e create,delete,modify \ --exclude '\..*\.swp' \ "$DWG_FOLDER" "$DB_FOLDER" \ --format '%:e %w%f' 2>&1 | while read event file do log "🔄 Event '$event' detected for file: $file" date +%s > "$timestamp_file" # Start the regeneration check in background (only one instance) if [ ! -f "$regeneration_lock" ]; then ( touch "$regeneration_lock" while true; do current_time=$(date +%s) last_event_time=$(cat "$timestamp_file") time_diff=$((current_time - last_event_time)) if [ $time_diff -ge $debounce_delay ]; then log "⏳ No new events for $debounce_delay seconds, regenerating manifest..." python /app/generate_manifest.py 2>&1 | while read line; do log "[MANIFEST] $line"; done rm "$regeneration_lock" break fi sleep 1 done ) & fi done # If inotifywait exits, log error and wait before restarting log "⚠️ File watcher stopped. Checking mount status..." mount | grep "$DWG_FOLDER" || log "No specific mount for $DWG_FOLDER found" mount | grep "$DB_FOLDER" || log "No specific mount for $DB_FOLDER found" log "⏳ Restarting in 5 seconds..." sleep 5 done } # Start Nginx in the background log "Starting Nginx..." nginx -g "daemon off;" & NGINX_PID=$! log "Nginx started with PID: $NGINX_PID" # Start the scheduler app log "Starting scheduler app..." python /app/scheduler_app.py & SCHEDULER_PID=$! log "Scheduler app started with PID: $SCHEDULER_PID" # Watch for file changes and regenerate manifest watch_files & WATCHER_PID=$! log "File watcher started with PID: $WATCHER_PID" # Handle SIGTERM and other signals gracefully trap 'log "Received signal to terminate. Shutting down..."; kill $WATCHER_PID; kill $NGINX_PID; kill $SCHEDULER_PID; exit 0' SIGTERM SIGINT # Start Gunicorn with proper logging to stderr/stdout log "Starting Gunicorn..." exec gunicorn --workers=4 --bind=0.0.0.0:5000 --log-level=info --access-logfile=- --error-logfile=- --capture-output wsgi:app