Add migrate.sh script to easily run db migration/seed in production
This commit is contained in:
@@ -57,3 +57,23 @@ this directory:
|
|||||||
Deployed to Fly.io (`fly.toml`). After a domain changes, re-run
|
Deployed to Fly.io (`fly.toml`). After a domain changes, re-run
|
||||||
`src/scripts/register-webhooks.ts` with production env vars to point Printful's
|
`src/scripts/register-webhooks.ts` with production env vars to point Printful's
|
||||||
and Webflow's webhooks at the new domain — see issue #3 for the full checklist.
|
and Webflow's webhooks at the new domain — see issue #3 for the full checklist.
|
||||||
|
|
||||||
|
### Running migrations/seed against production
|
||||||
|
|
||||||
|
The deployed image only contains the compiled binary (see `Dockerfile`) — no
|
||||||
|
source, no `bun_modules`, no migration files — so these can't be run from
|
||||||
|
`fly ssh console` on the API app itself. Instead, use `migrate.sh` at the repo
|
||||||
|
root, which tunnels to the Postgres app (`blade-and-brawn-db`, legacy/unmanaged
|
||||||
|
Fly Postgres) via `fly proxy`, fetches the production `DATABASE_URL` for you,
|
||||||
|
and runs the scripts against it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./migrate.sh migrate # db:migrate:latest (default if no argument given)
|
||||||
|
./migrate.sh seed # db:seed
|
||||||
|
./migrate.sh both # both, in order
|
||||||
|
```
|
||||||
|
|
||||||
|
Both underlying scripts prompt for a `y/N` confirmation before touching the
|
||||||
|
database, and `db:seed` is idempotent (skips seeding if the default rows
|
||||||
|
already exist). If the tunneled connection fails on TLS, legacy Postgres
|
||||||
|
sometimes needs `?sslmode=disable` appended — edit `migrate.sh` if so.
|
||||||
|
|||||||
Executable
+52
@@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
PG_APP="blade-and-brawn-db"
|
||||||
|
API_APP="blade-and-brawn-api"
|
||||||
|
LOCAL_PORT=5433
|
||||||
|
|
||||||
|
proxy_pid=""
|
||||||
|
cleanup() {
|
||||||
|
if [[ -n "$proxy_pid" ]]; then
|
||||||
|
kill "$proxy_pid" 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
echo "Fetching production DATABASE_URL from $API_APP..." >&2
|
||||||
|
prod_url=$(fly ssh console -a "$API_APP" -C "printenv DATABASE_URL" 2>/dev/null | grep -m1 '^postgres')
|
||||||
|
if [[ -z "$prod_url" ]]; then
|
||||||
|
echo "Failed to fetch DATABASE_URL from $API_APP" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
tunneled_url=$(echo "$prod_url" | sed -E "s#@[^/]+/#@localhost:${LOCAL_PORT}/#")
|
||||||
|
|
||||||
|
echo "Starting tunnel to $PG_APP on localhost:${LOCAL_PORT}..." >&2
|
||||||
|
fly proxy "${LOCAL_PORT}:5432" -a "$PG_APP" &
|
||||||
|
proxy_pid=$!
|
||||||
|
|
||||||
|
echo "Waiting for tunnel..." >&2
|
||||||
|
for _ in $(seq 1 30); do
|
||||||
|
nc -z localhost "$LOCAL_PORT" 2>/dev/null && break
|
||||||
|
sleep 0.5
|
||||||
|
done
|
||||||
|
|
||||||
|
target="${1:-migrate}"
|
||||||
|
|
||||||
|
case "$target" in
|
||||||
|
migrate)
|
||||||
|
DATABASE_URL="$tunneled_url" bun run --filter @blade-and-brawn/api db:migrate:latest
|
||||||
|
;;
|
||||||
|
seed)
|
||||||
|
DATABASE_URL="$tunneled_url" bun run --filter @blade-and-brawn/api db:seed
|
||||||
|
;;
|
||||||
|
both)
|
||||||
|
DATABASE_URL="$tunneled_url" bun run --filter @blade-and-brawn/api db:migrate:latest
|
||||||
|
DATABASE_URL="$tunneled_url" bun run --filter @blade-and-brawn/api db:seed
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $0 [migrate|seed|both]" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
Reference in New Issue
Block a user