#!/bin/bash # ══════════════════════════════════════════════════════════════════════════════ # Vision Studio — Deploy manuel vers pavillon80.changeip.org:444 # # Usage: ./scripts/deploy_prod.sh [branch] # Défaut: main # ══════════════════════════════════════════════════════════════════════════════ set -euo pipefail BRANCH="${1:-main}" HOST="discord@176.182.176.84" PORT=444 REMOTE_DIR="/home/discord/Bots/VisionApp" SSH_OPTS="-o StrictHostKeyChecking=no -p $PORT" log() { echo "[deploy] $(date '+%F %T') $*"; } log "Deploy de la branche $BRANCH vers $HOST:$PORT..." # 1. Rsync du code log "Rsync du code..." rsync -az --no-o --no-g \ --exclude '.git/' --exclude '.env' --exclude '.env.*' \ --exclude 'data/' --exclude 'logs/' --exclude '*.log' --exclude 'nohup.out' \ --exclude '__pycache__/' --exclude 'venv/' --exclude '.venv/' \ --exclude '*.db' --exclude '*.db-journal' --exclude '*.db-wal' --exclude '*.db-shm' \ --exclude '.vscode/' --exclude '.idea/' \ -e "ssh $SSH_OPTS" \ . "$HOST:$REMOTE_DIR/" # 2. Vérification syntaxe sur le serveur log "Vérification syntaxe..." ssh $SSH_OPTS "$HOST" "cd $REMOTE_DIR && find . -name '*.py' -not -path '*/__pycache__/*' -not -path '*/.git/*' -not -path '*/venv/*' | head -20 | xargs -I{} python3 -m py_compile {} 2>&1 | head -5" # 3. Rebuild + restart Docker log "Rebuild Docker..." ssh $SSH_OPTS "$HOST" "cd $REMOTE_DIR && docker compose build --no-cache vision 2>&1 | tail -3" log "Restart du conteneur..." ssh $SSH_OPTS "$HOST" "cd $REMOTE_DIR && docker compose up -d --force-recreate vision 2>&1 | tail -3" # 4. Health check log "Health check..." sleep 8 STATUS=$(ssh $SSH_OPTS "$HOST" "curl -s -m 5 http://localhost:1890/health 2>/dev/null || echo ''") if echo "$STATUS" | grep -q '"status":"ok"'; then log "✅ Deploy réussi — Health OK" ssh $SSH_OPTS "$HOST" "docker logs --tail 5 vision-bot 2>&1" else log "❌ Health check échoué" ssh $SSH_OPTS "$HOST" "docker logs --tail 20 vision-bot 2>&1" exit 1 fi