Spaces:
Paused
Paused
fix(entrypoint): pick newer of latest.dump/latest.sql.gz by mtime β prevents stale dump from overriding fresh sql.gz on cold boot (root cause of 05-22 data revert)
ac254eb verified | # Sidecar entrypoint: prepare PGDATA, optionally restore from /backup, then hand | |
| # off to supervisord which runs postgres + redis + backup loop + sub2api. | |
| set -euo pipefail | |
| : "${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set as a Space secret}" | |
| : "${POSTGRES_USER:=sub2api}" | |
| : "${POSTGRES_DB:=sub2api}" | |
| : "${PGDATA:=/var/lib/postgresql/data}" | |
| : "${BACKUP_DIR:=/backup}" | |
| mkdir -p "$PGDATA" | |
| chmod 0700 "$PGDATA" | |
| NEEDS_INIT=0 | |
| # RESTORE_KIND: 0 none | 1 plain-sql.gz | 2 pg_dump custom (.dump) | |
| # Pick the NEWER of the two by mtime so a stale .dump never wins over a | |
| # fresh .sql.gz (we got burned by this once β backup loop only refreshed | |
| # .sql.gz, the .dump was the original migration dump frozen in time). | |
| RESTORE_KIND=0 | |
| if [ ! -s "$PGDATA/PG_VERSION" ]; then | |
| NEEDS_INIT=1 | |
| DUMP_MTIME=0 | |
| GZ_MTIME=0 | |
| [ -s "$BACKUP_DIR/latest.dump" ] && DUMP_MTIME=$(stat -c%Y "$BACKUP_DIR/latest.dump" 2>/dev/null || echo 0) | |
| [ -s "$BACKUP_DIR/latest.sql.gz" ] && GZ_MTIME=$( stat -c%Y "$BACKUP_DIR/latest.sql.gz" 2>/dev/null || echo 0) | |
| if [ "$DUMP_MTIME" -gt 0 ] && [ "$DUMP_MTIME" -ge "$GZ_MTIME" ]; then | |
| RESTORE_KIND=2 | |
| echo "[init] picked latest.dump (mtime=$DUMP_MTIME >= sql.gz mtime=$GZ_MTIME)" | |
| elif [ "$GZ_MTIME" -gt 0 ]; then | |
| RESTORE_KIND=1 | |
| echo "[init] picked latest.sql.gz (mtime=$GZ_MTIME > dump mtime=$DUMP_MTIME)" | |
| fi | |
| fi | |
| if [ $NEEDS_INIT -eq 1 ]; then | |
| echo "[init] initdb in $PGDATA" | |
| PWFILE="$(mktemp)" | |
| printf '%s' "$POSTGRES_PASSWORD" > "$PWFILE" | |
| initdb -D "$PGDATA" \ | |
| -U "$POSTGRES_USER" \ | |
| --pwfile="$PWFILE" \ | |
| --auth=scram-sha-256 \ | |
| --encoding=UTF8 \ | |
| --locale=C | |
| rm -f "$PWFILE" | |
| { | |
| echo "listen_addresses = '127.0.0.1'" | |
| echo "unix_socket_directories = '/tmp'" | |
| echo "log_timezone = 'Asia/Shanghai'" | |
| echo "timezone = 'Asia/Shanghai'" | |
| } >> "$PGDATA/postgresql.conf" | |
| cat > "$PGDATA/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 | |
| fi | |
| # Bootstrap PG via pg_ctl to create DB / restore, then stop before supervisord. | |
| echo "[init] starting bootstrap postgres" | |
| pg_ctl -D "$PGDATA" -l /tmp/pg-bootstrap.log \ | |
| -o "-c listen_addresses=127.0.0.1 -c unix_socket_directories=/tmp" \ | |
| -w -t 30 start | |
| EXISTS=$(psql -h /tmp -U "$POSTGRES_USER" -d postgres -tAc \ | |
| "SELECT 1 FROM pg_database WHERE datname='$POSTGRES_DB'" || echo "") | |
| if [ "$EXISTS" != "1" ]; then | |
| echo "[init] creating database $POSTGRES_DB" | |
| psql -h /tmp -U "$POSTGRES_USER" -d postgres \ | |
| -c "CREATE DATABASE \"$POSTGRES_DB\"" | |
| fi | |
| case "$RESTORE_KIND" in | |
| 1) | |
| echo "[init] restoring plain SQL $BACKUP_DIR/latest.sql.gz into $POSTGRES_DB" | |
| if gunzip -c "$BACKUP_DIR/latest.sql.gz" \ | |
| | psql -h /tmp -U "$POSTGRES_USER" -d "$POSTGRES_DB" -v ON_ERROR_STOP=1; then | |
| echo "[init] restore ok" | |
| else | |
| echo "[init] restore FAILED β continuing with empty DB" | |
| fi | |
| ;; | |
| 2) | |
| echo "[init] restoring custom dump $BACKUP_DIR/latest.dump into $POSTGRES_DB" | |
| if pg_restore -h /tmp -U "$POSTGRES_USER" -d "$POSTGRES_DB" \ | |
| --clean --if-exists --no-owner --no-privileges \ | |
| "$BACKUP_DIR/latest.dump"; then | |
| echo "[init] restore ok" | |
| else | |
| echo "[init] pg_restore returned non-zero (often benign warnings) β continuing" | |
| fi | |
| ;; | |
| esac | |
| echo "[init] stopping bootstrap postgres" | |
| pg_ctl -D "$PGDATA" -m fast -w stop | |
| echo "[init] launching supervisord" | |
| exec /usr/bin/supervisord -c /etc/supervisord.conf -n | |