#!/usr/bin/env bash set -euo pipefail # ── Scrum Manager — On-Premise Kubernetes Deploy Script ───────────────────── # Run from the project root: bash k8s/overlays/on-premise/deploy.sh # ──────────────────────────────────────────────────────────────────────────── OVERLAY="k8s/overlays/on-premise" NAMESPACE="scrum-manager" REGISTRY="${REGISTRY:-}" # Optional: set to your registry, e.g. "192.168.1.10:5000" RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m' info() { echo -e "${GREEN}[INFO]${NC} $*"; } warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; } # ── Pre-flight checks ──────────────────────────────────────────────────────── info "Checking prerequisites..." command -v kubectl >/dev/null 2>&1 || error "kubectl not found" command -v docker >/dev/null 2>&1 || error "docker not found" kubectl cluster-info >/dev/null 2>&1 || error "Cannot reach Kubernetes cluster. Check kubeconfig." info "Prerequisites OK." # ── Multi-node: hostPath nodeAffinity reminder ─────────────────────────────── NODE_COUNT=$(kubectl get nodes --no-headers 2>/dev/null | wc -l) if [ "$NODE_COUNT" -gt 1 ]; then warn "Multi-node cluster detected ($NODE_COUNT nodes)." warn "MySQL data is stored at /mnt/data/mysql on ONE node only." warn "Open k8s/overlays/on-premise/mysql-pv.yaml and uncomment" warn "the nodeAffinity block, setting it to the correct node hostname." warn "Run: kubectl get nodes to list hostnames." read -rp "Press ENTER to continue anyway, or Ctrl+C to abort and fix first..." fi # ── Build Docker images ────────────────────────────────────────────────────── info "Building Docker images..." BACKEND_TAG="${REGISTRY:+${REGISTRY}/}scrum-backend:latest" FRONTEND_TAG="${REGISTRY:+${REGISTRY}/}scrum-frontend:latest" docker build -t "$BACKEND_TAG" -f server/Dockerfile server/ docker build -t "$FRONTEND_TAG" -f Dockerfile . # ── Push or load images into cluster ──────────────────────────────────────── if [ -n "$REGISTRY" ]; then info "Pushing images to registry $REGISTRY..." docker push "$BACKEND_TAG" docker push "$FRONTEND_TAG" else warn "No REGISTRY set. Attempting to load images via 'docker save | ssh'..." warn "If you have a single-node cluster and Docker runs on the same host," warn "set imagePullPolicy: Never in the deployments (already set)." warn "For multi-node, set REGISTRY= before running this script." warn "" warn " Alternatively, load images manually on each node with:" warn " docker save scrum-backend:latest | ssh NODE docker load" warn " docker save scrum-frontend:latest | ssh NODE docker load" fi # ── Apply Kubernetes manifests ──────────────────────────────────────────────── info "Applying manifests via kustomize..." kubectl apply -k "$OVERLAY" # ── Wait for rollout ────────────────────────────────────────────────────────── info "Waiting for MySQL to become ready (this can take up to 90s on first run)..." kubectl rollout status deployment/mysql -n "$NAMESPACE" --timeout=120s || \ warn "MySQL rollout timed out — check: kubectl describe pod -l app.kubernetes.io/name=mysql -n $NAMESPACE" info "Waiting for backend..." kubectl rollout status deployment/backend -n "$NAMESPACE" --timeout=90s || \ warn "Backend rollout timed out — check: kubectl logs -l app.kubernetes.io/name=backend -n $NAMESPACE" info "Waiting for frontend..." kubectl rollout status deployment/frontend -n "$NAMESPACE" --timeout=60s || \ warn "Frontend rollout timed out." # ── Show access info ────────────────────────────────────────────────────────── echo "" info "Deploy complete! Access the app:" NODEPORT=$(kubectl get svc frontend -n "$NAMESPACE" -o jsonpath='{.spec.ports[0].nodePort}' 2>/dev/null || echo "") NODE_IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}' 2>/dev/null || echo "") if [ -n "$NODEPORT" ]; then echo "" echo -e " NodePort: ${GREEN}http://${NODE_IP}:${NODEPORT}${NC}" fi echo "" echo -e " Ingress: ${GREEN}http://scrum.local${NC} (add '$NODE_IP scrum.local' to /etc/hosts)" echo "" echo "Useful commands:" echo " kubectl get pods -n $NAMESPACE" echo " kubectl logs -f deployment/backend -n $NAMESPACE" echo " kubectl logs -f deployment/mysql -n $NAMESPACE"