Some checks failed
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker API / Build + push API (push) Waiting to run
Docker API / Deploy API on stage (push) Blocked by required conditions
Docker Public / Build + push Public (test + latest) (push) Has been cancelled
Docker Web / Build + push Web (push) Has been cancelled
Docker Public / Deploy :test → test.food-market.kz (push) Has been cancelled
Docker Web / Deploy Web on stage (push) Has been cancelled
05.10.2026 общий postgres-инстанс с чужими боевыми базами (sklad, purchase, calcman, calcman_staging, makesales + мусорная старая food_market) вынесен из compose прода food-market в отдельный compose-проект shared-postgres (контейнер shared-postgres, порт 5434, том food-market-postgres-data external). Прод food-market поднимается в собственный контейнер food-market-prod-postgres (порт 5437, том food-market-prod-postgres-data). Простой при разделении — 12с, соседи живы. См. docs/shared-postgres-followup-progress.md. Этот коммит синхронизирует репозиторий, чтобы следующий деплой из main не воскресил старую раскладку: - deploy/docker-compose.yml: container_name/port/volume приведены к прод-файлу (food-market-prod-postgres, 127.0.0.1:5437, food-market-prod-postgres-data). - deploy/shared-postgres/ (новое): документационная копия соседнего compose'а, с явной пометкой «food-market им не управляет». - deploy/food-market-backup.sh / anonymize-prod.sh / db-schema-diff.sh: defaults FM_PG_CONTAINER / FM_PROD_CONT = food-market-prod-postgres. - docs/RUNBOOK.md: новый раздел «Postgres на prod-vm» с таблицей трёх инстансов и явным запретом трогать shared-postgres из наших скриптов. - docs/backup-restore.md: контейнер в таблице и примерах — новый. Guards (не в репе — живут в ~/deploy-stage.sh и ~/quality-watchdog.sh) расширены симметрично: стенду запрещены shared-postgres, food-market-prod- postgres[-data], 5434/5437; проду — food-market-postgres-data (чужие данные). Проверка: docker compose config/ps на prod-vm shared-postgres не упоминают, grep по репе — ни один скрипт не делает docker exec в shared-postgres.
109 lines
4.3 KiB
Bash
Executable file
109 lines
4.3 KiB
Bash
Executable file
#!/usr/bin/env bash
|
||
#
|
||
# Sprint 21: сравнение схемы БД stage vs prod.
|
||
#
|
||
# Делает `pg_dump --schema-only` с обеих БД, diff'ит. Если выводит
|
||
# непустой diff — миграция не доехала или local-only изменения.
|
||
#
|
||
# Подразумевает что обе БД доступны (например через SSH-туннель или
|
||
# pg_dump --host=<host>). Дефолтные подключения:
|
||
# stage = docker exec food-market-stage-postgres pg_dump (через ssh prod-vm)
|
||
# prod = docker exec food-market-prod-postgres pg_dump (через ssh prod-vm)
|
||
#
|
||
# ВАЖНО: прод-контейнер — `food-market-prod-postgres` (с 2026-10-05). Соседний
|
||
# `shared-postgres` на той же машине обслуживает ЧУЖИЕ боевые базы (sklad,
|
||
# purchase, calcman, calcman_staging, makesales) и в diff не участвует.
|
||
# См. docs/shared-postgres-followup-progress.md.
|
||
#
|
||
# Usage:
|
||
# deploy/db-schema-diff.sh [--stage-host HOST] [--prod-host HOST]
|
||
# [--quick] # без TOAST/sequence-details
|
||
# [--dry-run] # печать только команд
|
||
#
|
||
# Выход:
|
||
# 0 — схемы идентичны
|
||
# 1 — есть различия (печатает diff)
|
||
# 2 — ошибка получения дампа
|
||
|
||
set -uo pipefail
|
||
|
||
STAGE_HOST="${FM_STAGE_HOST:-nns@192.168.1.190}"
|
||
PROD_HOST="${FM_PROD_HOST:-nns@admin.food-market.kz}"
|
||
STAGE_CONT="${FM_STAGE_CONT:-food-market-stage-postgres}"
|
||
PROD_CONT="${FM_PROD_CONT:-food-market-prod-postgres}"
|
||
DB="${FM_PG_DB:-food_market}"
|
||
DB_USER="${FM_PG_USER:-food_market}"
|
||
QUICK=0
|
||
DRY_RUN=0
|
||
|
||
while [[ $# -gt 0 ]]; do
|
||
case "$1" in
|
||
--stage-host) STAGE_HOST="$2"; shift 2 ;;
|
||
--prod-host) PROD_HOST="$2"; shift 2 ;;
|
||
--quick) QUICK=1; shift ;;
|
||
--dry-run) DRY_RUN=1; shift ;;
|
||
--help|-h) grep -E '^#( |$)' "$0" | sed 's/^# \?//'; exit 0 ;;
|
||
*) echo "Unknown: $1" >&2; exit 2 ;;
|
||
esac
|
||
done
|
||
|
||
# Флаги pg_dump для schema-only сравнения. --schema-only + --no-owner +
|
||
# --no-privileges чтобы дамп был стабильный без role-mismatch'ей между
|
||
# инстансами. --no-comments — выключаем COMMENT'ы (они часто шумят).
|
||
PGDUMP_FLAGS="--schema-only --no-owner --no-privileges --no-comments"
|
||
if [[ $QUICK -eq 1 ]]; then
|
||
PGDUMP_FLAGS="$PGDUMP_FLAGS --exclude-table-data=pg_*"
|
||
fi
|
||
|
||
TMP_DIR=$(mktemp -d)
|
||
trap "rm -rf $TMP_DIR" EXIT
|
||
STAGE_SQL="$TMP_DIR/stage.sql"
|
||
PROD_SQL="$TMP_DIR/prod.sql"
|
||
|
||
log() { echo "[$(date -Iseconds)] $*" >&2; }
|
||
|
||
dump_remote() {
|
||
local host="$1" container="$2" out="$3"
|
||
log "dump from $host (container $container) → $out"
|
||
if [[ $DRY_RUN -eq 1 ]]; then
|
||
echo "[dry-run] ssh $host docker exec $container pg_dump $PGDUMP_FLAGS -U $DB_USER -d $DB > $out"
|
||
touch "$out"
|
||
return
|
||
fi
|
||
ssh -o ConnectTimeout=10 "$host" "docker exec $container pg_dump $PGDUMP_FLAGS -U $DB_USER -d $DB" > "$out" 2>/dev/null \
|
||
|| { log "FAIL: dump from $host"; return 2; }
|
||
}
|
||
|
||
dump_remote "$STAGE_HOST" "$STAGE_CONT" "$STAGE_SQL" || exit 2
|
||
dump_remote "$PROD_HOST" "$PROD_CONT" "$PROD_SQL" || exit 2
|
||
|
||
# Нормализация: убираем строки которые всегда отличаются (комментарии,
|
||
# даты, version-header'ы, OID'ы):
|
||
normalize() {
|
||
sed -e '/^-- /d' \
|
||
-e '/^SET /d' \
|
||
-e '/^SELECT pg_catalog.set_config/d' \
|
||
-e '/^[[:space:]]*$/d' "$1"
|
||
}
|
||
|
||
# Применяем нормализацию ин-плейс и сравниваем.
|
||
normalize "$STAGE_SQL" > "$TMP_DIR/stage.norm"
|
||
normalize "$PROD_SQL" > "$TMP_DIR/prod.norm"
|
||
|
||
log "comparing…"
|
||
if diff -u "$TMP_DIR/prod.norm" "$TMP_DIR/stage.norm" > "$TMP_DIR/diff" 2>&1; then
|
||
echo "✓ Схемы идентичны (stage == prod)"
|
||
exit 0
|
||
fi
|
||
|
||
LINES=$(wc -l < "$TMP_DIR/diff")
|
||
echo "✗ Найдены различия: $LINES строк diff'a"
|
||
echo
|
||
echo "===== diff (prod → stage) ====="
|
||
cat "$TMP_DIR/diff"
|
||
echo "==============================="
|
||
echo
|
||
echo "Если разница — новые миграции stage → prod, применить их перед deploy."
|
||
echo "Если разница — local-only изменения на prod, разобраться вручную."
|
||
exit 1
|