feat: add npm run update for safe API deploys
Ship schema to replicas without the data repair that disables subscriptions and stalls replication. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+5
-11
@@ -122,27 +122,21 @@ cp deploy/replicas.env.example deploy/replicas.env # once; add real DSNs
|
|||||||
bash deploy/sync-replica-schema.sh --init # once, when schemas already match
|
bash deploy/sync-replica-schema.sh --init # once, when schemas already match
|
||||||
```
|
```
|
||||||
|
|
||||||
For every release on **publisher** (`/var/www/superadmin/api`):
|
For every release, on the publisher (`/var/www/superadmin/api`) and on each replica API directory:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git pull
|
npm run update
|
||||||
npm run replicas:sync # 1) DDL on replicas 2) migrate deploy 3) repair data drift if any
|
|
||||||
npx prisma generate
|
|
||||||
npm run build
|
|
||||||
pm2 restart superadmin-api
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
On the publisher this pulls, installs, applies DDL on the replicas before `prisma migrate deploy`, refreshes subscriptions with `copy_data=false`, builds, and restarts `superadmin-api`. On a replica (no `deploy/replicas.env`) the same command only pulls, installs, generates, builds, and restarts. It does not run `sync-replica-data.sh`.
|
||||||
|
|
||||||
Check only:
|
Check only:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run replicas:check # schema + subscription + row counts (settings, tenants, …)
|
npm run replicas:check # schema + subscription + row counts (settings, tenants, …)
|
||||||
```
|
```
|
||||||
|
|
||||||
Force data realign from publisher (rare — e.g. after fixing subscriber permissions):
|
Do not use `npm run replicas:sync` or `npm run replicas:repair-data` for a release. Both run the data repair, which disables a subscription and recopies rows without advancing the replication origin. The apply worker then dies replaying old WAL. `npm run update` is the release command.
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run replicas:repair-data
|
|
||||||
```
|
|
||||||
|
|
||||||
`replicas:sync` runs `sync-replica-data.sh --repair-if-needed` automatically when
|
`replicas:sync` runs `sync-replica-data.sh --repair-if-needed` automatically when
|
||||||
`settings` / `setting_templates` / `tenants` counts differ from publisher.
|
`settings` / `setting_templates` / `tenants` counts differ from publisher.
|
||||||
|
|||||||
Executable
+77
@@ -0,0 +1,77 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# One-step API update.
|
||||||
|
#
|
||||||
|
# Master (deploy/replicas.env present): pull, install, ship DDL to replicas,
|
||||||
|
# generate, build, restart. Schema is applied on subscribers before the publisher
|
||||||
|
# migrates, then subscriptions are refreshed with copy_data=false.
|
||||||
|
#
|
||||||
|
# Replica (no replicas.env): pull, install, generate, build, restart.
|
||||||
|
# Does not migrate and does not touch the subscription.
|
||||||
|
#
|
||||||
|
# Never calls sync-replica-data.sh. That repair disables subscriptions and
|
||||||
|
# leaves the replication origin behind, so the apply worker dies on replay.
|
||||||
|
#
|
||||||
|
# Usage (inside the API directory, or from anywhere):
|
||||||
|
# bash deploy/update.sh # master if replicas.env exists, else replica
|
||||||
|
# bash deploy/update.sh --master
|
||||||
|
# bash deploy/update.sh --replica
|
||||||
|
# PM2_APP=superadmin-api bash deploy/update.sh
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
API_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
cd "$API_DIR"
|
||||||
|
|
||||||
|
MODE="${1:-auto}"
|
||||||
|
case "$MODE" in
|
||||||
|
auto|--master|--replica) ;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $0 [--master|--replica]" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [[ "$MODE" == auto ]]; then
|
||||||
|
if [[ -f "$API_DIR/deploy/replicas.env" ]]; then
|
||||||
|
MODE=--master
|
||||||
|
else
|
||||||
|
MODE=--replica
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$MODE" == --master && ! -f "$API_DIR/deploy/replicas.env" ]]; then
|
||||||
|
echo "deploy/replicas.env is missing, so this host is not the publisher." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
APP="${PM2_APP:-superadmin-api}"
|
||||||
|
echo "== update $MODE app=$APP dir=$API_DIR"
|
||||||
|
|
||||||
|
git pull --ff-only
|
||||||
|
npm ci
|
||||||
|
|
||||||
|
if [[ "$MODE" == --master ]]; then
|
||||||
|
bash "$API_DIR/deploy/sync-replica-schema.sh"
|
||||||
|
fi
|
||||||
|
|
||||||
|
npx prisma generate
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
restart_pm2() {
|
||||||
|
if pm2 describe "$APP" >/dev/null 2>&1; then
|
||||||
|
pm2 restart "$APP"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
local user
|
||||||
|
for user in montime ubuntu; do
|
||||||
|
if id "$user" >/dev/null 2>&1 && sudo -u "$user" pm2 describe "$APP" >/dev/null 2>&1; then
|
||||||
|
sudo -u "$user" pm2 restart "$APP"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "pm2 process '$APP' not found. Set PM2_APP to the name from: pm2 list" >&2
|
||||||
|
pm2 list || true
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
restart_pm2
|
||||||
|
echo "== update done ($MODE)"
|
||||||
@@ -35,6 +35,7 @@
|
|||||||
"prisma:repair-khanegi-ui-config": "ts-node --transpile-only prisma/repair-khanegi-ui-config.ts",
|
"prisma:repair-khanegi-ui-config": "ts-node --transpile-only prisma/repair-khanegi-ui-config.ts",
|
||||||
"prisma:copy-sms-between-tenants": "ts-node --transpile-only prisma/copy-sms-between-tenants.ts",
|
"prisma:copy-sms-between-tenants": "ts-node --transpile-only prisma/copy-sms-between-tenants.ts",
|
||||||
"prisma:list-tenants": "ts-node --transpile-only prisma/list-tenants.ts",
|
"prisma:list-tenants": "ts-node --transpile-only prisma/list-tenants.ts",
|
||||||
|
"update": "bash deploy/update.sh",
|
||||||
"replicas:sync": "bash deploy/sync-replica-schema.sh && bash deploy/sync-replica-data.sh --repair-if-needed",
|
"replicas:sync": "bash deploy/sync-replica-schema.sh && bash deploy/sync-replica-data.sh --repair-if-needed",
|
||||||
"replicas:check": "bash deploy/sync-replica-schema.sh --check && bash deploy/sync-replica-data.sh --check",
|
"replicas:check": "bash deploy/sync-replica-schema.sh --check && bash deploy/sync-replica-data.sh --check",
|
||||||
"replicas:repair-data": "bash deploy/sync-replica-data.sh --repair",
|
"replicas:repair-data": "bash deploy/sync-replica-data.sh --repair",
|
||||||
|
|||||||
Reference in New Issue
Block a user