#!/bin/bash set -e # Apply DB migrations once (idempotent — both processes also call init_db # defensively in case alembic was skipped during local dev). alembic upgrade head # Start the background routing processor (poll loop). python -m app.processor & PROCESSOR_PID=$! # Start the standalone scheduler (subscription bootstrap + APScheduler cron # jobs). Runs in its own process so the FastAPI server below can scale to # multiple uvicorn workers without duplicating cron work. python -m app.scheduler_main & SCHEDULER_PID=$! # Forward SIGTERM/SIGINT and EXIT to the background processes so the # container shuts down cleanly. trap "kill ${PROCESSOR_PID} ${SCHEDULER_PID} 2>/dev/null; \ wait ${PROCESSOR_PID} ${SCHEDULER_PID} 2>/dev/null" EXIT TERM INT # FastAPI in the foreground. UVICORN_WORKERS controls horizontal scaling # of the webhook receiver. Safe to bump because scheduler + processor are # in their own processes. exec uvicorn app.main:app \ --host "${HOST:-0.0.0.0}" \ --port "${PORT:-8000}" \ --workers "${UVICORN_WORKERS:-2}"