| #!/bin/bash |
| set -e |
|
|
| PG_VERSION=15 |
| PG_BIN=/usr/lib/postgresql/$PG_VERSION/bin |
| PG_DATA=/data/pgdata |
| PG_LOG=/data/pgdata/pg.log |
|
|
| : "${POSTGRES_USER:=root}" |
| : "${POSTGRES_PASSWORD:=123456}" |
| : "${POSTGRES_DB:=new-api}" |
| : "${SQL_DSN:=postgresql://root:123456@127.0.0.1:5432/new-api?sslmode=disable}" |
|
|
| export LANG=en_US.UTF-8 |
| export LC_ALL=en_US.UTF-8 |
| export SQL_DSN |
|
|
| mkdir -p "$PG_DATA" |
| chown -R postgres:postgres "$PG_DATA" |
|
|
| if [ ! -f "$PG_DATA/PG_VERSION" ]; then |
| echo "Initializing PostgreSQL data directory..." |
|
|
| su postgres -c "$PG_BIN/initdb -D '$PG_DATA' --locale=en_US.UTF-8" |
|
|
| if [ ! -f "$PG_DATA/postgresql.conf" ]; then |
| echo "FATAL: initdb did not create postgresql.conf" >&2 |
| exit 1 |
| fi |
| fi |
|
|
| echo "Writing PostgreSQL configuration..." |
|
|
| cat > "$PG_DATA/pg_hba.conf" << EOF |
| local all all trust |
| host all all 127.0.0.1/32 scram-sha-256 |
| host all all ::1/128 scram-sha-256 |
| EOF |
|
|
| |
| if ! grep -q "^listen_addresses" "$PG_DATA/postgresql.conf" 2>/dev/null; then |
| echo "listen_addresses = '127.0.0.1,::1'" >> "$PG_DATA/postgresql.conf" |
| fi |
|
|
| |
| if ! grep -q "^fsync = off" "$PG_DATA/postgresql.conf" 2>/dev/null; then |
| echo "Applying PostgreSQL storage optimizations..." |
|
|
| cat >> "$PG_DATA/postgresql.conf" << EOF |
| |
| # Hugging Face Spaces storage optimizations |
| fsync = off |
| synchronous_commit = off |
| full_page_writes = off |
| EOF |
| fi |
|
|
| |
| if [ -f "$PG_DATA/postmaster.pid" ]; then |
| OLD_PID=$(head -1 "$PG_DATA/postmaster.pid") |
|
|
| if ! kill -0 "$OLD_PID" 2>/dev/null; then |
| echo "Removing stale PostgreSQL PID file, old PID: $OLD_PID" |
| rm -f "$PG_DATA/postmaster.pid" |
| fi |
| fi |
|
|
| |
| chown -R postgres:postgres "$PG_DATA" |
| chmod 0700 "$PG_DATA" |
|
|
| |
| |
| for dir in \ |
| base \ |
| global \ |
| pg_commit_ts \ |
| pg_dynshmem \ |
| pg_logical \ |
| pg_logical/snapshots \ |
| pg_logical/mappings \ |
| pg_multixact \ |
| pg_multixact/members \ |
| pg_multixact/offsets \ |
| pg_notify \ |
| pg_replslot \ |
| pg_serial \ |
| pg_snapshots \ |
| pg_stat \ |
| pg_stat_tmp \ |
| pg_subtrans \ |
| pg_tblspc \ |
| pg_twophase \ |
| pg_wal \ |
| pg_wal/archive_status; do |
|
|
| if [ ! -d "$PG_DATA/$dir" ]; then |
| echo "Recreating missing directory: $dir" |
| mkdir -p "$PG_DATA/$dir" |
| fi |
| done |
|
|
| chown -R postgres:postgres "$PG_DATA" |
|
|
| rm -f "$PG_LOG" |
|
|
| echo "Starting PostgreSQL..." |
|
|
| su postgres -c "$PG_BIN/pg_ctl -D '$PG_DATA' -l '$PG_LOG' start" || { |
| echo "=== PostgreSQL log ===" |
| cat "$PG_LOG" 2>/dev/null || echo "(no PostgreSQL log file)" |
| exit 1 |
| } |
|
|
| echo "Waiting for PostgreSQL to be ready..." |
|
|
| for i in $(seq 1 120); do |
| if su postgres -c "$PG_BIN/pg_isready -q -h 127.0.0.1 -p 5432"; then |
| echo "PostgreSQL is ready." |
| break |
| fi |
|
|
| if [ "$i" -eq 120 ]; then |
| echo "PostgreSQL startup timeout." |
| echo "=== PostgreSQL log ===" |
| cat "$PG_LOG" 2>/dev/null || echo "(no PostgreSQL log file)" |
| exit 1 |
| fi |
|
|
| sleep 1 |
| done |
|
|
| echo "Creating or fixing database user and database..." |
|
|
| |
| if ! su postgres -c "$PG_BIN/psql -tAc \"SELECT 1 FROM pg_roles WHERE rolname='$POSTGRES_USER'\"" | grep -q 1; then |
| echo "Creating PostgreSQL user: $POSTGRES_USER" |
| su postgres -c "$PG_BIN/psql -c \"CREATE USER \\\"$POSTGRES_USER\\\" WITH PASSWORD '$POSTGRES_PASSWORD'\"" |
| fi |
|
|
| |
| |
| echo "Resetting PostgreSQL password for user: $POSTGRES_USER" |
| su postgres -c "$PG_BIN/psql -c \"ALTER USER \\\"$POSTGRES_USER\\\" WITH PASSWORD '$POSTGRES_PASSWORD'\"" |
|
|
| |
| if ! su postgres -c "$PG_BIN/psql -tAc \"SELECT 1 FROM pg_database WHERE datname='$POSTGRES_DB'\"" | grep -q 1; then |
| echo "Creating PostgreSQL database: $POSTGRES_DB" |
| su postgres -c "$PG_BIN/psql -c \"CREATE DATABASE \\\"$POSTGRES_DB\\\" OWNER \\\"$POSTGRES_USER\\\"\"" |
| fi |
|
|
| |
| echo "Fixing database owner..." |
| su postgres -c "$PG_BIN/psql -c \"ALTER DATABASE \\\"$POSTGRES_DB\\\" OWNER TO \\\"$POSTGRES_USER\\\"\"" |
|
|
| echo "Testing PostgreSQL login..." |
|
|
| PGPASSWORD="$POSTGRES_PASSWORD" "$PG_BIN/psql" \ |
| "postgresql://$POSTGRES_USER@127.0.0.1:5432/$POSTGRES_DB?sslmode=disable" \ |
| -c "SELECT current_user, current_database();" || { |
| echo "FATAL: PostgreSQL login test failed." |
| echo "=== PostgreSQL log ===" |
| cat "$PG_LOG" 2>/dev/null || echo "(no PostgreSQL log file)" |
| exit 1 |
| } |
|
|
| cd /data |
|
|
| echo "Starting NewAPI..." |
| echo "SQL_DSN=$SQL_DSN" |
|
|
| /new-api & |
| NEWAPI_PID=$! |
|
|
| cleanup() { |
| echo "Shutting down..." |
|
|
| if kill -0 "$NEWAPI_PID" 2>/dev/null; then |
| kill "$NEWAPI_PID" 2>/dev/null || true |
| wait "$NEWAPI_PID" 2>/dev/null || true |
| fi |
|
|
| su postgres -c "$PG_BIN/pg_ctl -D '$PG_DATA' stop -m fast" || true |
|
|
| exit 0 |
| } |
|
|
| trap cleanup SIGTERM SIGINT |
|
|
| wait "$NEWAPI_PID" |
| EXIT_CODE=$? |
|
|
| echo "NewAPI exited with code $EXIT_CODE" |
|
|
| su postgres -c "$PG_BIN/pg_ctl -D '$PG_DATA' stop -m fast" || true |
|
|
| exit "$EXIT_CODE" |