File size: 7,009 Bytes
20be6bc
 
 
9f11f19
20be6bc
 
90976d4
 
 
9dc4461
90976d4
 
20be6bc
90976d4
 
 
 
 
 
20be6bc
 
90976d4
 
 
 
 
20be6bc
90976d4
 
 
 
 
 
d8d83be
922680e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37be533
3cfa99e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37be533
3cfa99e
37be533
3cfa99e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37be533
 
3cfa99e
 
 
37be533
3cfa99e
 
 
37be533
 
3cfa99e
 
 
 
 
 
 
 
 
 
 
 
37be533
 
90976d4
 
 
d8d83be
20be6bc
90976d4
20be6bc
 
4cdf901
20be6bc
 
636310b
e85994b
 
 
 
 
 
 
 
636310b
 
90976d4
 
 
 
 
 
636310b
 
 
 
 
20be6bc
90976d4
20be6bc
9f11f19
e85994b
20be6bc
636310b
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#!/usr/bin/env bash
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