#!/usr/bin/env bash set -euo pipefail ROLE="${1:-web}" shift || true case "$ROLE" in web) echo "[entrypoint] Running alembic upgrade head" alembic upgrade head echo "[entrypoint] Starting hypercorn on :8080" # create_app is a factory — the `()` tells hypercorn to call it once # and serve the returned Quart (ASGI) app, rather than treating the # function itself as the application (which it then mis-invokes as WSGI). # Default 4 workers (was 2): each worker is one asyncio loop, and a large # file download occupies its worker for the transfer — 2 was too few once the # GPU agent + the browser's thumbnail grid hit /images concurrently (they # queued behind each other). Env-tunable via HYPERCORN_WORKERS. exec hypercorn \ --bind 0.0.0.0:8080 \ --workers "${HYPERCORN_WORKERS:-4}" \ --access-logfile - \ "backend.app:create_app()" ;; worker) QUEUES="${CELERY_QUEUES:-default,import,thumbnail}" CONCURRENCY="${CELERY_CONCURRENCY:-2}" echo "[entrypoint] Starting Celery worker queues=$QUEUES concurrency=$CONCURRENCY" exec celery -A backend.app.celery_app:celery worker \ --loglevel=info \ -Q "$QUEUES" \ --concurrency="$CONCURRENCY" ;; scheduler) QUEUES="${CELERY_QUEUES:-maintenance,scan}" echo "[entrypoint] Starting Celery beat+worker queues=$QUEUES" exec celery -A backend.app.celery_app:celery worker \ --beat \ --loglevel=info \ -Q "$QUEUES" \ --concurrency=1 ;; ml-worker) echo "[entrypoint] Ensuring ML models present in /models..." python -m backend.app.scripts.download_models echo "[entrypoint] Starting ML Celery worker (ml queue)" exec celery -A backend.app.celery_app:celery worker \ --loglevel=info \ -Q ml \ --concurrency=1 ;; shell|bash) exec /bin/bash "$@" ;; alembic) exec alembic "$@" ;; *) echo "[entrypoint] Unknown role: $ROLE" >&2 echo "[entrypoint] Valid roles: web | worker | scheduler | ml-worker | shell | alembic" >&2 exit 1 ;; esac