#!/usr/bin/env bash set -euo pipefail # AgentHub LAN Deployment Script — Phase 1 # Déploie AgentHub sur serveur LAN en docker compose avec build local # Usage: ./scripts/deploy-lan.sh [ssh-user] SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(dirname "$SCRIPT_DIR")" SERVER_IP="${1:-}" SSH_USER="${2:-alexandre}" REMOTE_DIR="/opt/agenthub" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color usage() { echo "Usage: $0 [ssh-user]" echo "" echo "Example:" echo " $0 192.168.9.23" echo " $0 192.168.9.23 ubuntu" exit 1 } if [[ -z "$SERVER_IP" ]]; then echo -e "${RED}❌ Error: Server IP required${NC}" usage fi echo "╔════════════════════════════════════════════════════╗" echo "║ AgentHub LAN Deployment — Phase 1 ║" echo "╚════════════════════════════════════════════════════╝" echo "" echo "Target: ${SSH_USER}@${SERVER_IP}:${REMOTE_DIR}" echo "" # ───────────────────────────────────────────────────────── # Step 1 — Vérifier la connexion SSH # ───────────────────────────────────────────────────────── echo "[1/7] Testing SSH connection..." if ! ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no "${SSH_USER}@${SERVER_IP}" "echo OK" &>/dev/null; then echo -e "${RED}❌ SSH connection failed${NC}" echo "" echo "Please ensure:" echo " 1. Server ${SERVER_IP} is reachable (ping ${SERVER_IP})" echo " 2. SSH is enabled on the server" echo " 3. SSH key is configured or password auth is enabled" echo "" echo "To configure SSH key:" echo " ssh-copy-id ${SSH_USER}@${SERVER_IP}" exit 1 fi echo -e "${GREEN}✅ SSH connection OK${NC}" echo "" # ───────────────────────────────────────────────────────── # Step 2 — Vérifier Docker sur le serveur # ───────────────────────────────────────────────────────── echo "[2/7] Checking Docker on remote server..." if ! ssh "${SSH_USER}@${SERVER_IP}" "docker --version && docker compose version" &>/dev/null; then echo -e "${YELLOW}⚠️ Docker not installed or not accessible${NC}" echo "" echo "Install Docker on the server first:" echo " ssh ${SSH_USER}@${SERVER_IP}" echo " curl -fsSL https://get.docker.com | sudo sh" echo " sudo usermod -aG docker ${SSH_USER}" echo " exit" echo " # Then reconnect and retry this script" exit 1 fi echo -e "${GREEN}✅ Docker is installed${NC}" echo "" # ───────────────────────────────────────────────────────── # Step 3 — Créer le répertoire distant # ───────────────────────────────────────────────────────── echo "[3/7] Creating remote directory..." ssh "${SSH_USER}@${SERVER_IP}" "sudo mkdir -p ${REMOTE_DIR} && sudo chown ${SSH_USER}:${SSH_USER} ${REMOTE_DIR}" echo -e "${GREEN}✅ Remote directory created${NC}" echo "" # ───────────────────────────────────────────────────────── # Step 4 — Copier les fichiers nécessaires # ───────────────────────────────────────────────────────── echo "[4/7] Copying files to server..." # Liste des fichiers/dossiers à copier FILES_TO_COPY=( "Dockerfile" ".dockerignore" "package.json" "package-lock.json" "tsconfig.json" "tsconfig.build.json" "src/" "drizzle/" "drizzle.config.ts" "scripts/migrate.ts" "scripts/seed.ts" "compose.lan-direct.yml" ".env.lan" ) # Créer une archive temporaire TMPDIR=$(mktemp -d) ARCHIVE="${TMPDIR}/agenthub-deploy.tar.gz" cd "$REPO_ROOT" tar czf "$ARCHIVE" "${FILES_TO_COPY[@]}" 2>/dev/null || { echo -e "${RED}❌ Failed to create archive${NC}" rm -rf "$TMPDIR" exit 1 } # Copier l'archive scp -q "$ARCHIVE" "${SSH_USER}@${SERVER_IP}:${REMOTE_DIR}/agenthub-deploy.tar.gz" # Extraire sur le serveur ssh "${SSH_USER}@${SERVER_IP}" "cd ${REMOTE_DIR} && tar xzf agenthub-deploy.tar.gz && rm agenthub-deploy.tar.gz" # Nettoyer rm -rf "$TMPDIR" echo -e "${GREEN}✅ Files copied${NC}" echo "" # ───────────────────────────────────────────────────────── # Step 5 — Arrêter l'ancien stack (si existe) # ───────────────────────────────────────────────────────── echo "[5/7] Stopping existing stack (if any)..." ssh "${SSH_USER}@${SERVER_IP}" "cd ${REMOTE_DIR} && docker compose -f compose.lan-direct.yml down 2>/dev/null || true" echo -e "${GREEN}✅ Stack stopped${NC}" echo "" # ───────────────────────────────────────────────────────── # Step 6 — Démarrer le nouveau stack # ───────────────────────────────────────────────────────── echo "[6/7] Starting AgentHub stack..." ssh "${SSH_USER}@${SERVER_IP}" "cd ${REMOTE_DIR} && docker compose -f compose.lan-direct.yml up -d --build" # Attendre que le healthcheck passe echo "Waiting for healthcheck..." sleep 10 echo -e "${GREEN}✅ Stack started${NC}" echo "" # ───────────────────────────────────────────────────────── # Step 7 — Vérifier le déploiement # ───────────────────────────────────────────────────────── echo "[7/7] Verifying deployment..." # Health check via SSH HEALTH_STATUS=$(ssh "${SSH_USER}@${SERVER_IP}" "curl -s http://localhost:3000/healthz" || echo "FAIL") if echo "$HEALTH_STATUS" | grep -q '"status":"ok"'; then echo -e "${GREEN}✅ Health check passed${NC}" echo "" echo "╔════════════════════════════════════════════════════╗" echo "║ 🎉 Deployment Successful! ║" echo "╚════════════════════════════════════════════════════╝" echo "" echo "AgentHub is now running at:" echo " 📡 HTTP: http://${SERVER_IP}:3000" echo " 🔌 WebSocket: ws://${SERVER_IP}:3000/agents" echo "" echo "Endpoints:" echo " Health: http://${SERVER_IP}:3000/healthz" echo " API: http://${SERVER_IP}:3000/api/v1/" echo "" echo "Next steps:" echo " 1. Test the API: curl http://${SERVER_IP}:3000/healthz" echo " 2. View logs: ssh ${SSH_USER}@${SERVER_IP} 'cd ${REMOTE_DIR} && docker compose -f compose.lan-direct.yml logs -f app'" echo " 3. Run smoke tests: ./test/smoke-lan-2-agents.sh ${SERVER_IP}" echo "" else echo -e "${RED}❌ Health check failed${NC}" echo "" echo "Response: $HEALTH_STATUS" echo "" echo "Check logs:" echo " ssh ${SSH_USER}@${SERVER_IP} 'cd ${REMOTE_DIR} && docker compose -f compose.lan-direct.yml logs app'" exit 1 fi