#!/bin/bash # K3s Deployment Script - Optimizado para tiempo mínimo # Uso: ./deploy.sh [build|deploy|all|status|clean] set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" # Colores RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # Cargar credenciales si existen CREDS_FILE="$HOME/.secrets/credentials.env" [[ -f "$CREDS_FILE" ]] && source "$CREDS_FILE" # Configuración K3S_HOST="${K8S_MASTER_HOST:-hp62a}" NAMESPACE="student-enrollment" API_IMAGE="academia-api:latest" FRONTEND_IMAGE="academia-frontend:latest" log() { echo -e "${GREEN}[$(date +%T)]${NC} $1"; } warn() { echo -e "${YELLOW}[$(date +%T)]${NC} $1"; } err() { echo -e "${RED}[$(date +%T)]${NC} $1" >&2; } build_images() { log "=== Construyendo imágenes Docker (paralelo) ===" cd "$PROJECT_ROOT" # Build en paralelo docker build -t "$API_IMAGE" -f deploy/docker/Dockerfile.api . & PID_API=$! docker build -t "$FRONTEND_IMAGE" -f deploy/docker/Dockerfile.frontend . & PID_FRONTEND=$! # Esperar ambos wait $PID_API && log "✓ API imagen construida" || { err "✗ Error construyendo API"; exit 1; } wait $PID_FRONTEND && log "✓ Frontend imagen construida" || { err "✗ Error construyendo Frontend"; exit 1; } } transfer_images() { log "=== Transfiriendo imágenes a k3s ===" # Exportar y transferir en paralelo docker save "$API_IMAGE" | ssh "$K3S_HOST" "sudo k3s ctr images import -" & PID_API=$! docker save "$FRONTEND_IMAGE" | ssh "$K3S_HOST" "sudo k3s ctr images import -" & PID_FRONTEND=$! wait $PID_API && log "✓ API transferida" || { err "✗ Error transfiriendo API"; exit 1; } wait $PID_FRONTEND && log "✓ Frontend transferida" || { err "✗ Error transfiriendo Frontend"; exit 1; } } deploy_k3s() { log "=== Desplegando en k3s con Kustomize ===" # Aplicar con kustomize ssh "$K3S_HOST" "cd /tmp && sudo kubectl apply -k -" < <(kubectl kustomize "$SCRIPT_DIR") log "=== Esperando despliegues ===" # Esperar SQL Server primero (es dependencia) ssh "$K3S_HOST" "sudo kubectl -n $NAMESPACE rollout status deployment/sqlserver --timeout=180s" || warn "SQL Server timeout" # Esperar API y Frontend en paralelo ssh "$K3S_HOST" "sudo kubectl -n $NAMESPACE rollout status deployment/student-api --timeout=120s" & PID_API=$! ssh "$K3S_HOST" "sudo kubectl -n $NAMESPACE rollout status deployment/student-frontend --timeout=60s" & PID_FRONTEND=$! wait $PID_API && log "✓ API desplegada" || warn "API timeout" wait $PID_FRONTEND && log "✓ Frontend desplegado" || warn "Frontend timeout" } show_status() { log "=== Estado del despliegue ===" ssh "$K3S_HOST" "sudo kubectl -n $NAMESPACE get pods -o wide" echo "" ssh "$K3S_HOST" "sudo kubectl -n $NAMESPACE get svc" echo "" ssh "$K3S_HOST" "sudo kubectl -n $NAMESPACE get ingress 2>/dev/null || true" } clean() { warn "=== Limpiando namespace $NAMESPACE ===" ssh "$K3S_HOST" "sudo kubectl delete namespace $NAMESPACE --ignore-not-found" log "✓ Namespace eliminado" } restart_pods() { log "=== Reiniciando pods (rolling restart) ===" ssh "$K3S_HOST" "sudo kubectl -n $NAMESPACE rollout restart deployment/student-api" ssh "$K3S_HOST" "sudo kubectl -n $NAMESPACE rollout restart deployment/student-frontend" log "✓ Pods reiniciados" } # Main case "${1:-all}" in build) build_images ;; transfer) transfer_images ;; deploy) deploy_k3s show_status ;; all) build_images transfer_images deploy_k3s show_status ;; status) show_status ;; clean) clean ;; restart) restart_pods ;; *) echo "Uso: $0 [build|transfer|deploy|all|status|clean|restart]" exit 1 ;; esac log "=== Completado ==="