#!/usr/bin/env sh set -e # Ensure Flask CLI finds your app export FLASK_APP=run.py export FLASK_ENV=production # If arguments are passed and first arg is NOT "web", execute them directly # This allows: docker run celery -A app.celery_app:celery worker ... if [ $# -gt 0 ] && [ "$1" != "web" ]; then exec "$@" fi # --- Web service mode (default or explicit "web" argument) --- # --- Migrations with simple retry (no pg_isready needed) --- if [ "${RUN_DB_MIGRATIONS:-1}" = "1" ]; then ATTEMPTS="${MIGRATION_MAX_ATTEMPTS:-30}" # ~90s default with 3s sleep SLEEP_SECS="${MIGRATION_RETRY_SLEEP:-3}" i=1 echo "Applying migrations (up to $ATTEMPTS attempts)..." until flask db upgrade; do if [ "$i" -ge "$ATTEMPTS" ]; then echo "ERROR: Migrations failed after $ATTEMPTS attempts." exit 1 fi echo "DB not ready yet; retrying in ${SLEEP_SECS}s ($i/$ATTEMPTS)…" sleep "$SLEEP_SECS" i=$((i+1)) done # Run version check and data migrations (e.g., phash recomputation) echo "Checking app version and running data migrations..." flask version-check fi # --- Start Gunicorn --- GUNICORN_BIND="${GUNICORN_BIND:-0.0.0.0:5000}" GUNICORN_WORKERS="${GUNICORN_WORKERS:-8}" GUNICORN_THREADS="${GUNICORN_THREADS:-4}" GUNICORN_TIMEOUT="${GUNICORN_TIMEOUT:-180}" GUNICORN_OPTS="${GUNICORN_OPTS:-}" echo "Starting Gunicorn on ${GUNICORN_BIND} …" exec gunicorn \ --bind "${GUNICORN_BIND}" \ --workers "${GUNICORN_WORKERS}" \ --worker-class gthread \ --threads "${GUNICORN_THREADS}" \ --timeout "${GUNICORN_TIMEOUT}" \ --access-logfile - \ --error-logfile - \ ${GUNICORN_OPTS} \ run:app