myapi-hub / entrypoint.sh
Looknicemm's picture
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
Raw
History Blame Contribute Delete
3.72 kB
#!/bin/bash
# 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