Spaces:
Sleeping
Sleeping
| set -e | |
| log() { | |
| echo "[$(date -u +'%Y-%m-%dT%H:%M:%SZ')] $*" | |
| } | |
| log "======================================" | |
| log "PostgreSQL General HF Space starting" | |
| log "======================================" | |
| if [ -z "$POSTGRES_PASSWORD" ]; then | |
| log "ERROR: POSTGRES_PASSWORD is not set." | |
| log "Please set POSTGRES_PASSWORD in Hugging Face Space Secrets." | |
| exit 1 | |
| fi | |
| export POSTGRES_USER="${POSTGRES_USER:-admin}" | |
| export POSTGRES_DB="${POSTGRES_DB:-appdb}" | |
| # PostgreSQL runtime data directory: use Space local disk. | |
| export PGDATA="${PGDATA:-/home/user/pgdata}" | |
| # Mounted storage bucket directories. | |
| export DATA_DIR="${DATA_DIR:-/data}" | |
| export BACKUP_DIR="${BACKUP_DIR:-/data/backups}" | |
| export USER_FILE_DIR="${USER_FILE_DIR:-/data/files}" | |
| export EXPORT_DIR="${EXPORT_DIR:-/data/exports}" | |
| export GENERATED_DIR="${GENERATED_DIR:-/data/generated}" | |
| # Automatic backup interval, default: 1 hour. | |
| export BACKUP_INTERVAL_SECONDS="${BACKUP_INTERVAL_SECONDS:-3600}" | |
| log "Runtime configuration:" | |
| log "POSTGRES_USER=$POSTGRES_USER" | |
| log "POSTGRES_DB=$POSTGRES_DB" | |
| log "PGDATA=$PGDATA" | |
| log "DATA_DIR=$DATA_DIR" | |
| log "BACKUP_DIR=$BACKUP_DIR" | |
| log "USER_FILE_DIR=$USER_FILE_DIR" | |
| log "EXPORT_DIR=$EXPORT_DIR" | |
| log "GENERATED_DIR=$GENERATED_DIR" | |
| log "BACKUP_INTERVAL_SECONDS=$BACKUP_INTERVAL_SECONDS" | |
| log "Creating directories..." | |
| mkdir -p "$PGDATA" | |
| mkdir -p "$BACKUP_DIR" | |
| mkdir -p "$USER_FILE_DIR" | |
| mkdir -p "$EXPORT_DIR" | |
| mkdir -p "$GENERATED_DIR" | |
| # PostgreSQL needs a private data directory. Allow permission changes to fail on restricted runtimes. | |
| chown -R postgres:postgres "$PGDATA" || true | |
| chmod 700 "$PGDATA" || true | |
| chmod -R 755 "$DATA_DIR" || true | |
| log "Directory status:" | |
| ls -ld "$PGDATA" || true | |
| ls -ld "$DATA_DIR" || true | |
| ls -ld "$BACKUP_DIR" || true | |
| ls -ld "$USER_FILE_DIR" || true | |
| ls -ld "$EXPORT_DIR" || true | |
| ls -ld "$GENERATED_DIR" || true | |
| RESTORE_BACKUP=0 | |
| if [ ! -s "$PGDATA/PG_VERSION" ]; then | |
| log "No existing PostgreSQL data directory found." | |
| if [ -f "$BACKUP_DIR/latest.sql" ]; then | |
| log "Backup file found: $BACKUP_DIR/latest.sql" | |
| log "Database will be restored after PostgreSQL initialization." | |
| RESTORE_BACKUP=1 | |
| else | |
| log "No backup file found. A new database will be initialized." | |
| fi | |
| else | |
| log "Existing PostgreSQL data directory found." | |
| fi | |
| log "Starting PostgreSQL..." | |
| docker-entrypoint.sh postgres & | |
| POSTGRES_PID=$! | |
| log "Waiting for PostgreSQL to become ready..." | |
| until pg_isready -h 127.0.0.1 -p 5432 -U "$POSTGRES_USER"; do | |
| sleep 2 | |
| done | |
| log "PostgreSQL is ready." | |
| if [ "$RESTORE_BACKUP" = "1" ]; then | |
| log "Restoring database from $BACKUP_DIR/latest.sql ..." | |
| PGPASSWORD="$POSTGRES_PASSWORD" psql \ | |
| -h 127.0.0.1 \ | |
| -p 5432 \ | |
| -U "$POSTGRES_USER" \ | |
| -d "$POSTGRES_DB" \ | |
| < "$BACKUP_DIR/latest.sql" || { | |
| log "WARNING: Restore failed. Please check backup file." | |
| } | |
| log "Restore process finished." | |
| fi | |
| create_backup() { | |
| TIMESTAMP="$(date +%Y%m%d_%H%M%S)" | |
| BACKUP_FILE="$BACKUP_DIR/backup_${POSTGRES_DB}_${TIMESTAMP}.sql" | |
| LATEST_FILE="$BACKUP_DIR/latest.sql" | |
| log "Creating backup: $BACKUP_FILE" | |
| PGPASSWORD="$POSTGRES_PASSWORD" pg_dump \ | |
| -h 127.0.0.1 \ | |
| -p 5432 \ | |
| -U "$POSTGRES_USER" \ | |
| -d "$POSTGRES_DB" \ | |
| > "$BACKUP_FILE.tmp" | |
| mv "$BACKUP_FILE.tmp" "$BACKUP_FILE" | |
| cp "$BACKUP_FILE" "$LATEST_FILE" | |
| log "Backup saved: $BACKUP_FILE and $LATEST_FILE" | |
| } | |
| backup_loop() { | |
| log "Backup loop started. Interval: ${BACKUP_INTERVAL_SECONDS}s" | |
| while true; do | |
| sleep "$BACKUP_INTERVAL_SECONDS" | |
| if pg_isready -h 127.0.0.1 -p 5432 -U "$POSTGRES_USER"; then | |
| create_backup || log "WARNING: Backup failed." | |
| else | |
| log "WARNING: PostgreSQL is not ready. Backup skipped." | |
| fi | |
| done | |
| } | |
| if pg_isready -h 127.0.0.1 -p 5432 -U "$POSTGRES_USER"; then | |
| create_backup || log "WARNING: Initial backup failed." | |
| fi | |
| backup_loop & | |
| log "Checking PHP PostgreSQL extension for optional Adminer usage..." | |
| if php -m | grep -Ei "pgsql|pdo_pgsql" > /dev/null; then | |
| log "PHP PostgreSQL extension loaded." | |
| else | |
| log "WARNING: PHP PostgreSQL extension is not loaded. Adminer may not work." | |
| fi | |
| log "Starting FastAPI on port 7860..." | |
| log "API docs: /docs" | |
| log "Health: /api/health" | |
| uvicorn api:app --host 0.0.0.0 --port 7860 | |
| wait "$POSTGRES_PID" |