MyPal / start.sh
KhaledSalehKL1's picture
Upload folder using huggingface_hub
1da98b1 verified
Raw
History Blame Contribute Delete
4.28 kB
#!/usr/bin/env bash
# Boot script for the single-container HF Space:
# 1. (only when no external DB is configured) start an in-container
# PostgreSQL with pgvector and create the app's role/database/extensions,
# 2. start Redis,
# 3. start Ollama (embeddings),
# 4. launch supervisord, which keeps the FastAPI app and Celery worker alive
# and auto-restarts them if they crash or hang.
set -euo pipefail
PGBIN=/usr/lib/postgresql/16/bin
# ── Database selection ────────────────────────────────────────────────────────
# When POSTGRES_HOST points at an external database (e.g. a managed Supabase
# Postgres), we DON'T start the in-container Postgres β€” the app connects out
# instead, and the data persists independently of this ephemeral container.
# Only when the host is unset/localhost do we boot the bundled Postgres (the
# local-dev / no-external-DB path). The app reads the same POSTGRES_* vars, so
# nothing in the application code changes between the two modes.
PGHOST_CFG="${POSTGRES_HOST:-localhost}"
if [ -z "$PGHOST_CFG" ] || [ "$PGHOST_CFG" = "localhost" ] || [ "$PGHOST_CFG" = "127.0.0.1" ]; then
USE_LOCAL_PG=1
else
USE_LOCAL_PG=0
fi
if [ "$USE_LOCAL_PG" = "1" ]; then
PGDATA="/var/lib/postgresql/data"
echo "[start] No external DB configured β€” starting in-container PostgreSQL at ephemeral $PGDATA (DB resets on restart)"
export PGDATA
PGUSER_DB="${POSTGRES_USER:-9xaipal}"
PGPASS="${POSTGRES_PASSWORD:-9xaipal_dev_password}"
PGDB="${POSTGRES_DB:-9xaipal}"
PGPORT="${POSTGRES_PORT:-5432}"
mkdir -p "$PGDATA"
chown -R postgres:postgres "$(dirname "$PGDATA")" "$PGDATA"
chmod 700 "$PGDATA"
if [ ! -s "$PGDATA/PG_VERSION" ]; then
echo "[start] Initializing PostgreSQL cluster at $PGDATA"
su postgres -c "$PGBIN/initdb -D '$PGDATA' --auth-local=trust --auth-host=scram-sha-256 --encoding=UTF8"
fi
echo "[start] Starting PostgreSQL"
su postgres -c "$PGBIN/pg_ctl -D '$PGDATA' -o '-c listen_addresses=localhost -p $PGPORT' -w -t 60 start"
echo "[start] Ensuring role / database / extensions"
# The role/database name can start with a digit (e.g. "9xaipal"), which is an
# invalid *bare* SQL identifier β€” it must be double-quoted. Rather than fight
# the nested shell quoting of `su postgres -c "psql -c \"...\""`, we write the
# role SQL to a temp file: a file read by `psql -f` involves no shell, so the
# double-quoted identifier (and a DO block) pass through verbatim.
PG_INIT_SQL="$(mktemp /tmp/pg_init.XXXXXX.sql)"
cat > "$PG_INIT_SQL" <<SQL
DO \$do\$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = '${PGUSER_DB}') THEN
CREATE ROLE "${PGUSER_DB}" LOGIN PASSWORD '${PGPASS}';
ELSE
ALTER ROLE "${PGUSER_DB}" WITH LOGIN PASSWORD '${PGPASS}';
END IF;
END
\$do\$;
SQL
chown postgres:postgres "$PG_INIT_SQL"
su postgres -c "psql --no-psqlrc -p $PGPORT -v ON_ERROR_STOP=1 -f '$PG_INIT_SQL'"
rm -f "$PG_INIT_SQL"
# Create the database if absent. `createdb` takes the name/owner as plain CLI
# args, so a digit-leading name needs no SQL identifier quoting.
su postgres -c "psql --no-psqlrc -p $PGPORT -tAc \"SELECT 1 FROM pg_database WHERE datname='${PGDB}'\" | grep -q 1 \
|| createdb -p $PGPORT -O '${PGUSER_DB}' '${PGDB}'"
su postgres -c "psql --no-psqlrc -p $PGPORT -d '${PGDB}' -c 'CREATE EXTENSION IF NOT EXISTS vector; CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";'"
else
echo "[start] External PostgreSQL configured ($PGHOST_CFG) β€” skipping in-container Postgres; data persists in the managed database"
fi
echo "[start] Starting Redis"
redis-server --daemonize yes
echo "[start] Starting Ollama (embeddings: qwen3-embedding) on 127.0.0.1:11434"
ollama serve >/tmp/ollama.log 2>&1 &
for i in $(seq 1 30); do
ollama list >/dev/null 2>&1 && break
sleep 1
done
if ollama list 2>/dev/null | grep -q qwen3-embedding; then
echo "[start] Ollama ready; qwen3-embedding present"
else
echo "[start] WARNING: qwen3-embedding not found in Ollama; attempting pull"
ollama pull qwen3-embedding || echo "[start] WARNING: pull failed; embeddings will be unavailable"
fi
echo "[start] Launching supervised services (API + Celery worker)"
exec supervisord -c /code/supervisord.conf