fix: migrate with the owner role and a private health file

The app's database role cannot create tables in public, so migrations
failed with "permission denied for schema public". They now also load
/etc/esports/{prod,staging}-migrations.env, whose DATABASE_URL overrides
the app's. The health pre-check wrote a fixed /tmp file that another user
already owned, which silently skipped the live-match check; it uses mktemp.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-18 22:47:58 +00:00
parent 6ff5fe53c5
commit 331507ee40

View File

@@ -10,9 +10,11 @@ esac
case "$directory:$origin" in case "$directory:$origin" in
/opt/esports:https://esports.vash.software) /opt/esports:https://esports.vash.software)
environment=/etc/esports/prod.env environment=/etc/esports/prod.env
migration_environment=/etc/esports/prod-migrations.env
host_port=3100 ;; host_port=3100 ;;
/opt/esports-staging:https://esports-staging.vash.software) /opt/esports-staging:https://esports-staging.vash.software)
environment=/etc/esports-staging/staging.env environment=/etc/esports-staging/staging.env
migration_environment=/etc/esports/staging-migrations.env
host_port=3101 ;; host_port=3101 ;;
*) echo 'Unrecognized deployment target' >&2; exit 2 ;; *) echo 'Unrecognized deployment target' >&2; exit 2 ;;
esac esac
@@ -72,10 +74,11 @@ rollback() {
trap rollback ERR trap rollback ERR
port=$host_port port=$host_port
if [ "${FORCE_DEPLOY:-}" != 1 ] && curl --fail --silent --show-error "http://127.0.0.1:${port}/api/health" > /tmp/esports-health.json; then health=$(mktemp)
python3 - <<'PY' if [ "${FORCE_DEPLOY:-}" != 1 ] && curl --fail --silent --show-error "http://127.0.0.1:${port}/api/health" > "$health"; then
import json HEALTH_FILE=$health python3 - <<'PY'
data = json.load(open("/tmp/esports-health.json")) import json, os
data = json.load(open(os.environ["HEALTH_FILE"]))
active = int(data.get("activeMatches") or data.get("irc", {}).get("activeLobbies") or 0) active = int(data.get("activeMatches") or data.get("irc", {}).get("activeLobbies") or 0)
if active: if active:
raise SystemExit(f"{active} matches are still live. Drain them from the admin page, or set FORCE_DEPLOY=1.") raise SystemExit(f"{active} matches are still live. Drain them from the admin page, or set FORCE_DEPLOY=1.")
@@ -118,8 +121,10 @@ sudo docker run --rm --network backend --env-file "$environment" \
pg_restore --list "/backups/$BACKUP_FILE" >/dev/null' pg_restore --list "/backups/$BACKUP_FILE" >/dev/null'
echo "Verified $environment_name database backup at $backup_dir/$backup_name" echo "Verified $environment_name database backup at $backup_dir/$backup_name"
sudo docker run --rm --network backend --env-file "$environment" "$image" \ # The app's database role cannot create tables; the migrations file overrides
bun scripts/migrate.ts # DATABASE_URL with the owner role and keeps the rest (ROOT_ADMIN_USER_ID).
sudo docker run --rm --network backend --env-file "$environment" \
--env-file "$migration_environment" "$image" bun scripts/migrate.ts
write_release "$sha" write_release "$sha"
switched=1 switched=1