feat(infra): reverse replication and update script for marcos-vps
This commit is contained in:
Executable
+117
@@ -0,0 +1,117 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# ==============================================================================
|
||||||
|
# SCRIPT DE REPLICAÇÃO REVERSA: MARCOS-VPS (PROD) -> HOSTINGER (BACKUP/RÉPLICA)
|
||||||
|
# ==============================================================================
|
||||||
|
# Sincroniza schemas de negócio (TS_ERP, gpi, tracksteel, rdo) e storage
|
||||||
|
# da VPS Local (marcos-vps) para o Supabase na Hostinger (100.106.199.108 / 187.77.227.172).
|
||||||
|
# ==============================================================================
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
CYAN='\033[0;36m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
RED='\033[0;31m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
LOG_DIR="/root/Apps/TracksteelApp/scripts/logs"
|
||||||
|
mkdir -p "$LOG_DIR"
|
||||||
|
LOG_FILE="$LOG_DIR/sync_db_to_hostinger_$(date +'%Y%m%d').log"
|
||||||
|
|
||||||
|
log() {
|
||||||
|
local msg="[$(date +'%Y-%m-%d %H:%M:%S')] $1"
|
||||||
|
echo -e "$1"
|
||||||
|
echo -e "$msg" >> "$LOG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
log "\n${CYAN}======================================================${NC}"
|
||||||
|
log "${CYAN}🔄 Iniciando Replicação Reversa: marcos-vps -> Hostinger${NC}"
|
||||||
|
log "${CYAN}======================================================${NC}"
|
||||||
|
|
||||||
|
# Containers
|
||||||
|
SRC_DB_CONTAINER="supabase-db-rjbxu55kggzc59d4cmo133cf"
|
||||||
|
DEST_DB_CONTAINER="supabase-db-h0oggskgs0ws0sco8kc4s8ws"
|
||||||
|
|
||||||
|
# Determinar IP de Conexão com a Hostinger (preferência Tailscale, fallback IP público)
|
||||||
|
DEST_IP="100.106.199.108"
|
||||||
|
log "${YELLOW}📡 Testando conexão SSH com Hostinger via Tailscale ($DEST_IP)...${NC}"
|
||||||
|
|
||||||
|
if ! ssh -o BatchMode=yes -o ConnectTimeout=5 "root@$DEST_IP" "true" 2>/dev/null; then
|
||||||
|
log "${YELLOW}⚠️ Tailscale inacessível. Tentando IP público Hostinger (187.77.227.172)...${NC}"
|
||||||
|
DEST_IP="187.77.227.172"
|
||||||
|
if ! ssh -o BatchMode=yes -o ConnectTimeout=5 "root@$DEST_IP" "true" 2>/dev/null; then
|
||||||
|
log "${RED}❌ ERRO: Não foi possível conectar via SSH à Hostinger ($DEST_IP). Replicação abortada.${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
log "${GREEN}✅ Conectividade com Hostinger confirmada ($DEST_IP).${NC}"
|
||||||
|
|
||||||
|
# Lista de Schemas a sincronizar
|
||||||
|
SCHEMAS=('TS_ERP' 'gpi' 'tracksteel' 'rdo')
|
||||||
|
|
||||||
|
for schema in "${SCHEMAS[@]}"; do
|
||||||
|
EXISTS=$(docker exec "$SRC_DB_CONTAINER" psql -U postgres -d postgres -tAc \
|
||||||
|
"SELECT 1 FROM pg_namespace WHERE nspname = '$schema';" 2>/dev/null || echo "0")
|
||||||
|
|
||||||
|
if [ "$EXISTS" = "1" ]; then
|
||||||
|
log "${YELLOW}📦 Sincronizando schema: $schema...${NC}"
|
||||||
|
TMP_DUMP="/tmp/sync_rev_${schema}_$$.dump"
|
||||||
|
|
||||||
|
# 1. Gerar Dump local comprimido (marcos-vps)
|
||||||
|
docker exec -i "$SRC_DB_CONTAINER" pg_dump -U postgres -d postgres -n "\"$schema\"" -Fc > "$TMP_DUMP"
|
||||||
|
|
||||||
|
# 2. Transferir para Hostinger via SCP
|
||||||
|
scp -q -o BatchMode=yes -o ConnectTimeout=5 "$TMP_DUMP" "root@$DEST_IP:$TMP_DUMP"
|
||||||
|
|
||||||
|
# 3. Restaurar na Hostinger e restabelecer permissões
|
||||||
|
ssh -o BatchMode=yes -o ConnectTimeout=5 "root@$DEST_IP" \
|
||||||
|
"docker cp '$TMP_DUMP' '$DEST_DB_CONTAINER:$TMP_DUMP' && \
|
||||||
|
(docker exec '$DEST_DB_CONTAINER' pg_restore -U postgres -d postgres --clean --if-exists --no-owner --no-privileges '$TMP_DUMP' || true) && \
|
||||||
|
docker exec '$DEST_DB_CONTAINER' psql -U postgres -d postgres -c \"GRANT USAGE ON SCHEMA \\\"$schema\\\" TO anon, authenticated, service_role, authenticator; GRANT ALL ON ALL TABLES IN SCHEMA \\\"$schema\\\" TO anon, authenticated, service_role; GRANT ALL ON ALL SEQUENCES IN SCHEMA \\\"$schema\\\" TO anon, authenticated, service_role; GRANT ALL ON ALL ROUTINES IN SCHEMA \\\"$schema\\\" TO anon, authenticated, service_role; ALTER DEFAULT PRIVILEGES IN SCHEMA \\\"$schema\\\" GRANT ALL ON TABLES TO anon, authenticated, service_role; ALTER DEFAULT PRIVILEGES IN SCHEMA \\\"$schema\\\" GRANT ALL ON SEQUENCES TO anon, authenticated, service_role; ALTER DEFAULT PRIVILEGES IN SCHEMA \\\"$schema\\\" GRANT ALL ON ROUTINES TO anon, authenticated, service_role; NOTIFY pgrst, 'reload schema';\" && \
|
||||||
|
rm -f '$TMP_DUMP' && \
|
||||||
|
docker exec '$DEST_DB_CONTAINER' rm -f '$TMP_DUMP'"
|
||||||
|
|
||||||
|
# 4. Limpar dump local
|
||||||
|
rm -f "$TMP_DUMP"
|
||||||
|
log "${GREEN} ↳ Schema $schema replicado na Hostinger com sucesso.${NC}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Sincronização de Metadados de Storage (buckets e objects)
|
||||||
|
log "${YELLOW}📁 Sincronizando metadados de Storage (buckets & objects)...${NC}"
|
||||||
|
STORAGE_SQL="/tmp/sync_storage_rev_$$.sql"
|
||||||
|
docker exec -i "$SRC_DB_CONTAINER" pg_dump -U postgres -d postgres -t storage.buckets -t storage.objects --data-only --on-conflict-do-nothing > "$STORAGE_SQL" 2>/dev/null || true
|
||||||
|
|
||||||
|
if [ -s "$STORAGE_SQL" ]; then
|
||||||
|
scp -q -o BatchMode=yes -o ConnectTimeout=5 "$STORAGE_SQL" "root@$DEST_IP:$STORAGE_SQL"
|
||||||
|
ssh -o BatchMode=yes -o ConnectTimeout=5 "root@$DEST_IP" \
|
||||||
|
"docker exec -i '$DEST_DB_CONTAINER' psql -U postgres -d postgres < '$STORAGE_SQL' >/dev/null 2>&1 && rm -f '$STORAGE_SQL'"
|
||||||
|
rm -f "$STORAGE_SQL"
|
||||||
|
log "${GREEN} ↳ Metadados de storage sincronizados na Hostinger.${NC}"
|
||||||
|
else
|
||||||
|
rm -f "$STORAGE_SQL"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Sincronização de arquivos físicos de Storage (MinIO)
|
||||||
|
SRC_STORAGE="/data/coolify/services/rjbxu55kggzc59d4cmo133cf/volumes/storage/"
|
||||||
|
DEST_STORAGE="/data/coolify/services/h0oggskgs0ws0sco8kc4s8ws/volumes/storage/"
|
||||||
|
|
||||||
|
if [ -d "$SRC_STORAGE" ]; then
|
||||||
|
log "${YELLOW}☁️ Sincronizando arquivos físicos do Storage para a Hostinger...${NC}"
|
||||||
|
rsync -aqz --delete -e "ssh -o BatchMode=yes -o ConnectTimeout=5" "$SRC_STORAGE" "root@$DEST_IP:$DEST_STORAGE" || true
|
||||||
|
log "${GREEN} ↳ Arquivos do Storage espelhados com sucesso na Hostinger.${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Validação final de integridade de tabelas em TS_ERP
|
||||||
|
ORIG_COUNT=$(docker exec "$SRC_DB_CONTAINER" psql -U postgres -d postgres -tAc "SELECT count(*) FROM pg_tables WHERE schemaname = 'TS_ERP';" 2>/dev/null || echo "0")
|
||||||
|
DEST_COUNT=$(ssh -o BatchMode=yes -o ConnectTimeout=5 "root@$DEST_IP" "docker exec '$DEST_DB_CONTAINER' psql -U postgres -d postgres -tAc \"SELECT count(*) FROM pg_tables WHERE schemaname = 'TS_ERP';\"" 2>/dev/null || echo "0")
|
||||||
|
|
||||||
|
log "${CYAN}📊 Validação de Integridade:${NC}"
|
||||||
|
log " - Tabelas TS_ERP (Origem marcos-vps): $ORIG_COUNT"
|
||||||
|
log " - Tabelas TS_ERP (Destino Hostinger): $DEST_COUNT"
|
||||||
|
|
||||||
|
if [ "$ORIG_COUNT" = "$DEST_COUNT" ] && [ "$ORIG_COUNT" != "0" ]; then
|
||||||
|
log "${GREEN}✨ Replicação reversa concluída com 100% de paridade!${NC}\n"
|
||||||
|
else
|
||||||
|
log "${YELLOW}⚠️ Aviso: Contagem de tabelas ($ORIG_COUNT vs $DEST_COUNT). Verifique os logs.${NC}\n"
|
||||||
|
fi
|
||||||
@@ -1,46 +1,61 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# ---------------------------------------------------------
|
# ---------------------------------------------------------
|
||||||
# TRACKSTEEL APP: DEPLOY E SINCRONIZAÇÃO
|
# TRACKSTEEL APP: DEPLOY & SINCRONIZAÇÃO (MARCOS-VPS -> PROD & HOSTINGER)
|
||||||
# ---------------------------------------------------------
|
# ---------------------------------------------------------
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
CYAN='\033[0;36m'
|
CYAN='\033[0;36m'
|
||||||
GREEN='\033[0;32m'
|
GREEN='\033[0;32m'
|
||||||
YELLOW='\033[1;33m'
|
YELLOW='\033[1;33m'
|
||||||
|
RED='\033[0;31m'
|
||||||
NC='\033[0m'
|
NC='\033[0m'
|
||||||
|
|
||||||
echo -e "\n${CYAN}🚀 Iniciando Ciclo Automático de Deploy TrackSteelAPP...${NC}"
|
echo -e "\n${CYAN}🚀 Iniciando Ciclo Automático de Deploy TrackSteel APP (marcos-vps)...${NC}"
|
||||||
|
|
||||||
echo -e "${YELLOW}📝 Sincronizando código...${NC}"
|
# 1. Git Commit & Push
|
||||||
|
echo -e "\n${YELLOW}📝 Sincronizando código com o repositório GitHub...${NC}"
|
||||||
git add .
|
git add .
|
||||||
|
|
||||||
if git diff-index --quiet HEAD --; then
|
if git diff-index --quiet HEAD --; then
|
||||||
echo -e "${GREEN}✨ Nenhuma nova alteração para comitar.${NC}"
|
echo -e "${GREEN}✨ Nenhuma nova alteração para comitar.${NC}"
|
||||||
else
|
else
|
||||||
TIMESTAMP=$(date +"%d/%m/%Y %H:%M:%S")
|
TIMESTAMP=$(date +"%d/%m/%Y %H:%M:%S")
|
||||||
MSG="${1:-🚀 Auto-deploy: TrackSteelAPP atualizado em $TIMESTAMP}"
|
MSG="${1:-🚀 Auto-deploy: TrackSteel APP atualizado em $TIMESTAMP}"
|
||||||
echo -e "${CYAN}📤 Criando novo commit: $MSG${NC}"
|
echo -e "${CYAN}📤 Criando novo commit: $MSG${NC}"
|
||||||
git commit -m "$MSG"
|
git commit -m "$MSG"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "${CYAN}📤 Sincronizando com os repositórios remotos (Gitea e GitHub)...${NC}"
|
echo -e "${CYAN}📤 Enviando alterações para o GitHub (origin main)...${NC}"
|
||||||
git push origin main
|
git push origin main
|
||||||
|
|
||||||
echo -e "\n${YELLOW}🔄 Disparando Deploy via API Oficial no Coolify (Hostinger)...${NC}"
|
# 2. Build local do Frontend
|
||||||
|
echo -e "\n${YELLOW}🔨 Executando build de produção local (npm run build)...${NC}"
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# 3. Reiniciar container do Tracksteel local
|
||||||
|
echo -e "\n${YELLOW}🔄 Atualizando container local tracksteel-app...${NC}"
|
||||||
|
if docker ps -a --format '{{.Names}}' | grep -q "^tracksteel-app$"; then
|
||||||
|
docker restart tracksteel-app
|
||||||
|
echo -e "${GREEN}✅ Container tracksteel-app reiniciado com sucesso!${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}ℹ️ Container tracksteel-app não encontrado no docker local.${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 4. Replicação Reversa de Banco de Dados para a Hostinger
|
||||||
|
echo -e "\n${YELLOW}🗄️ Executando replicação reversa de BD e Storage para a Hostinger...${NC}"
|
||||||
|
SCRIPT_SYNC="/root/Apps/TracksteelApp/scripts/sync_db_to_hostinger.sh"
|
||||||
|
if [ -f "$SCRIPT_SYNC" ]; then
|
||||||
|
chmod +x "$SCRIPT_SYNC"
|
||||||
|
"$SCRIPT_SYNC" || echo -e "${YELLOW}⚠️ Aviso: A replicação para Hostinger apresentou avisos ou falha de conexão.${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 5. Notificar Coolify da Hostinger para deploy de contingência
|
||||||
|
echo -e "\n${YELLOW}🌐 Atualizando app réplica no Coolify da Hostinger...${NC}"
|
||||||
COOLIFY_TOKEN="19|ZJKUbBgyeNGcKrVkMI5gJ1uMHDC39d9VIShHL473a60d9882"
|
COOLIFY_TOKEN="19|ZJKUbBgyeNGcKrVkMI5gJ1uMHDC39d9VIShHL473a60d9882"
|
||||||
TRACKSTEEL_UUID="i8o44gggg00o88ccc8oo48kk"
|
TRACKSTEEL_UUID="i8o44gggg00o88ccc8oo48kk"
|
||||||
curl -s -X GET "https://painel.reifonas.cloud/api/v1/deploy?uuid=${TRACKSTEEL_UUID}&force=false" \
|
curl -s -X GET "https://painel.reifonas.cloud/api/v1/deploy?uuid=${TRACKSTEEL_UUID}&force=false" \
|
||||||
-H "Authorization: Bearer $COOLIFY_TOKEN"
|
-H "Authorization: Bearer $COOLIFY_TOKEN" >/dev/null 2>&1 || true
|
||||||
echo -e "\n${GREEN}🚀 Deploy local (Hostinger) engatilhado com sucesso!${NC}"
|
echo -e "${GREEN}🚀 Deploy da réplica (Hostinger) acionado com sucesso!${NC}"
|
||||||
|
|
||||||
echo -e "\n${YELLOW}🌐 Sincronizando código e atualizando app na marcos-vps (100.97.2.16)...${NC}"
|
echo -e "\n${GREEN}🏁 Ciclo de deploy e replicação concluído com sucesso!${NC}\n"
|
||||||
ssh -o BatchMode=yes -o ConnectTimeout=5 root@100.97.2.16 \
|
|
||||||
"cd /root/Apps/TracksteelApp && git pull origin main && npm run build && docker restart tracksteel-app" \
|
|
||||||
&& echo -e "${GREEN}✅ App na marcos-vps atualizado com sucesso!${NC}" \
|
|
||||||
|| echo -e "${YELLOW}⚠️ Aviso: Falha ao atualizar app na marcos-vps via SSH.${NC}"
|
|
||||||
|
|
||||||
echo -e "\n${YELLOW}🗄️ Replicando Banco de Dados e Storage para marcos-vps...${NC}"
|
|
||||||
if [ -f "/root/Apps/TrackSteelAPP/scripts/sync_db_to_marcos.sh" ]; then
|
|
||||||
/root/Apps/TrackSteelAPP/scripts/sync_db_to_marcos.sh
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "\n${GREEN}🏁 Ciclo completo de deploy e replicação concluído com sucesso!${NC}\n"
|
|
||||||
|
|||||||
Reference in New Issue
Block a user