Spaces:
Running
Running
| set -euo pipefail | |
| echo "[boot] start redis" | |
| redis-server --bind 127.0.0.1 --port 6379 --daemonize yes | |
| export DATABASE_HOST="${DATABASE_HOST:-pg-newapi-codeatlantis666.f.aivencloud.com}" | |
| export DATABASE_PORT="${DATABASE_PORT:-22503}" | |
| export DATABASE_USER="${DATABASE_USER:-avnadmin}" | |
| export DATABASE_DBNAME="${DATABASE_DBNAME:-sub2api}" | |
| export DATABASE_SSLMODE="${DATABASE_SSLMODE:-require}" | |
| export DATABASE_SSLROOTCERT="${DATABASE_SSLROOTCERT:-/app/ca.pem}" | |
| if [ -z "${SQL_PASSWORD:-}" ]; then | |
| echo "[error] SQL_PASSWORD is required. Set Space Secret SQL_PASSWORD." | |
| echo "[error] You can provide either:" | |
| echo "[error] 1) password only (recommended with DATABASE_USER), or" | |
| echo "[error] 2) 'username:password' in SQL_PASSWORD." | |
| exit 1 | |
| fi | |
| if [ ! -f "${DATABASE_SSLROOTCERT}" ]; then | |
| echo "[error] CA cert not found at ${DATABASE_SSLROOTCERT}." | |
| echo "[error] Upload ca.pem and/or set DATABASE_SSLROOTCERT correctly." | |
| exit 1 | |
| fi | |
| if [[ "${SQL_PASSWORD}" == *:* ]]; then | |
| export DATABASE_USER="${SQL_PASSWORD%%:*}" | |
| export DATABASE_PASSWORD="${SQL_PASSWORD#*:}" | |
| else | |
| export DATABASE_PASSWORD="${SQL_PASSWORD}" | |
| fi | |
| if command -v psql >/dev/null 2>&1; then | |
| export PGHOST="${DATABASE_HOST}" | |
| export PGPORT="${DATABASE_PORT}" | |
| export PGUSER="${DATABASE_USER}" | |
| export PGPASSWORD="${DATABASE_PASSWORD}" | |
| export PGSSLMODE="${DATABASE_SSLMODE}" | |
| export PGSSLROOTCERT="${DATABASE_SSLROOTCERT}" | |
| if ! psql "dbname=postgres" -tAc "SELECT 1" >/dev/null 2>&1; then | |
| echo "[boot] 'postgres' database missing or inaccessible, trying to create it..." | |
| EXISTS_IN_TARGET=$(psql "dbname=${DATABASE_DBNAME}" -tAc "SELECT 1 FROM pg_database WHERE datname='postgres'" 2>/dev/null || true) | |
| if [ "${EXISTS_IN_TARGET}" != "1" ]; then | |
| if psql "dbname=${DATABASE_DBNAME}" -v ON_ERROR_STOP=1 -c "CREATE DATABASE postgres" >/dev/null 2>&1; then | |
| echo "[boot] created database: postgres" | |
| else | |
| echo "[warn] failed to create database 'postgres'. Auto setup may fail if upstream still requires dbname=postgres." | |
| fi | |
| else | |
| echo "[boot] database 'postgres' already exists" | |
| fi | |
| fi | |
| fi | |
| # sub2api AutoSetup currently uses a hard 60s migration context. | |
| # Pre-apply selected heavy migrations when needed to reduce timeout risk. | |
| is_true() { | |
| case "${1:-}" in | |
| 1|t|T|true|TRUE|yes|YES|y|Y|on|ON) return 0 ;; | |
| *) return 1 ;; | |
| esac | |
| } | |
| migration_applied() { | |
| local mig_name="$1" | |
| local out="" | |
| if ! is_true "${SCHEMA_MIGRATIONS_EXISTS:-}"; then | |
| echo "0" | |
| return 0 | |
| fi | |
| out=$(psql "dbname=${DATABASE_DBNAME}" -tAc "SELECT 1 FROM schema_migrations WHERE filename='${mig_name}' LIMIT 1" 2>/dev/null | tr -d '[:space:]' || true) | |
| if [ "${out}" = "1" ]; then | |
| echo "1" | |
| else | |
| echo "0" | |
| fi | |
| } | |
| preapply_migration() { | |
| local mig_name="$1" | |
| local mig_url="$2" | |
| local mig_sql="/tmp/${mig_name}" | |
| if curl -fsSL "${mig_url}" -o "${mig_sql}" >/dev/null 2>&1; then | |
| echo "[boot] pre-applying migration ${mig_name} ..." | |
| if PGOPTIONS="-c statement_timeout=0 -c lock_timeout=0" psql "dbname=${DATABASE_DBNAME}" -v ON_ERROR_STOP=1 -f "${mig_sql}" >/dev/null 2>&1; then | |
| echo "[boot] pre-apply ${mig_name} done" | |
| rm -f "${mig_sql}" || true | |
| return 0 | |
| fi | |
| echo "[warn] pre-apply ${mig_name} failed; AutoSetup will continue with built-in migration flow" | |
| rm -f "${mig_sql}" || true | |
| return 1 | |
| fi | |
| echo "[warn] failed to download migration ${mig_name} from ${mig_url}" | |
| return 1 | |
| } | |
| if command -v psql >/dev/null 2>&1 && command -v curl >/dev/null 2>&1; then | |
| SCHEMA_MIGRATIONS_EXISTS=$(psql "dbname=${DATABASE_DBNAME}" -tAc "SELECT to_regclass('public.schema_migrations') IS NOT NULL" 2>/dev/null | tr -d '[:space:]' || true) | |
| OPS_CORE_EXISTS=$(psql "dbname=${DATABASE_DBNAME}" -tAc "SELECT to_regclass('public.ops_error_logs') IS NOT NULL" 2>/dev/null | tr -d '[:space:]' || true) | |
| MIG_033_APPLIED="$(migration_applied "033_ops_monitoring_vnext.sql")" | |
| MIG_062_APPLIED="$(migration_applied "062_add_scheduler_and_usage_composite_indexes_notx.sql")" | |
| MIG_065_APPLIED="$(migration_applied "065_add_search_trgm_indexes.sql")" | |
| if [ "${MIG_033_APPLIED}" != "1" ]; then | |
| # If ops core tables already exist, avoid re-running destructive 033 pre-apply. | |
| if is_true "${OPS_CORE_EXISTS}"; then | |
| echo "[boot] skip pre-apply 033: ops schema already present" | |
| else | |
| preapply_migration \ | |
| "033_ops_monitoring_vnext.sql" \ | |
| "${MIG_033_URL:-https://raw.githubusercontent.com/Wei-Shaw/sub2api/main/backend/migrations/033_ops_monitoring_vnext.sql}" || true | |
| fi | |
| fi | |
| if [ "${MIG_062_APPLIED}" != "1" ]; then | |
| preapply_migration \ | |
| "062_add_scheduler_and_usage_composite_indexes_notx.sql" \ | |
| "${MIG_062_URL:-https://raw.githubusercontent.com/Wei-Shaw/sub2api/main/backend/migrations/062_add_scheduler_and_usage_composite_indexes_notx.sql}" || true | |
| fi | |
| if [ "${MIG_065_APPLIED}" != "1" ]; then | |
| preapply_migration \ | |
| "065_add_search_trgm_indexes.sql" \ | |
| "${MIG_065_URL:-https://raw.githubusercontent.com/Wei-Shaw/sub2api/main/backend/migrations/065_add_search_trgm_indexes.sql}" || true | |
| fi | |
| fi | |
| DATABASE_QUERY="sslmode=${DATABASE_SSLMODE}&sslrootcert=${DATABASE_SSLROOTCERT}" | |
| if [ -n "${DATABASE_QUERY_EXTRA:-}" ]; then | |
| DATABASE_QUERY="${DATABASE_QUERY}&${DATABASE_QUERY_EXTRA}" | |
| fi | |
| export DATABASE_URL="postgresql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_DBNAME}?${DATABASE_QUERY}" | |
| export POSTGRES_URL="${DATABASE_URL}" | |
| export DB_URL="${DATABASE_URL}" | |
| export REDIS_URL="${REDIS_URL:-redis://127.0.0.1:6379/0}" | |
| export PORT="${PORT:-8080}" | |
| export HOST="${HOST:-0.0.0.0}" | |
| export AUTO_SETUP="${AUTO_SETUP:-true}" | |
| export ADMIN_EMAIL="${ADMIN_EMAIL:-admin@sub2api.com}" | |
| if [ -n "${SUB2API_ADMIN_PASSWORD:-}" ] && [ -z "${ADMIN_PASSWORD:-}" ]; then | |
| export ADMIN_PASSWORD="${SUB2API_ADMIN_PASSWORD}" | |
| fi | |
| if [ -z "${ADMIN_PASSWORD:-}" ]; then | |
| echo "[error] ADMIN_PASSWORD is required. Set Space Secret ADMIN_PASSWORD (or SUB2API_ADMIN_PASSWORD)." | |
| exit 1 | |
| fi | |
| export SERVER_HOST="${HOST}" | |
| export SERVER_PORT="${PORT}" | |
| export DATABASE_HOST="${DATABASE_HOST}" | |
| export DATABASE_PORT="${DATABASE_PORT}" | |
| export DATABASE_USER="${DATABASE_USER}" | |
| export DATABASE_PASSWORD="${DATABASE_PASSWORD}" | |
| export DATABASE_DBNAME="${DATABASE_DBNAME}" | |
| export DATABASE_SSLMODE="${DATABASE_SSLMODE}" | |
| export REDIS_HOST="${REDIS_HOST:-127.0.0.1}" | |
| export REDIS_PORT="${REDIS_PORT:-6379}" | |
| export REDIS_DB="${REDIS_DB:-0}" | |
| export REDIS_PASSWORD="${REDIS_PASSWORD:-}" | |
| export REDIS_ENABLE_TLS="${REDIS_ENABLE_TLS:-false}" | |
| echo "[boot] DATABASE_URL=postgresql://${DATABASE_USER}:******@${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_DBNAME}?sslmode=${DATABASE_SSLMODE}&sslrootcert=${DATABASE_SSLROOTCERT}" | |
| echo "[boot] REDIS_URL=${REDIS_URL}" | |
| echo "[boot] APP_PORT=${PORT}" | |
| echo "[boot] ADMIN_EMAIL=${ADMIN_EMAIL}" | |
| # Start sub2api with the original entrypoint discovered from the base image. | |
| mkdir -p /app/data | |
| exec /app/sub2api | |