#!/usr/bin/env bash # Deploy Sankofa Portal to r630-01 # VMID: 7801, IP: 10.160.0.11 set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" SANKOFA_PROJECT="${SANKOFA_PROJECT:-/home/intlc/projects/Sankofa}" source "$SCRIPT_DIR/env.r630-01.example" 2>/dev/null || true # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[✓]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } # Configuration PROXMOX_HOST="${PROXMOX_HOST:-192.168.11.11}" VMID="${VMID_SANKOFA_PORTAL:-7801}" CONTAINER_IP="${SANKOFA_PORTAL_IP:-10.160.0.11}" API_URL="${NEXT_PUBLIC_GRAPHQL_ENDPOINT:-http://10.160.0.10:4000/graphql}" API_WS_URL="${NEXT_PUBLIC_GRAPHQL_WS_ENDPOINT:-ws://10.160.0.10:4000/graphql-ws}" KEYCLOAK_URL="${KEYCLOAK_URL:-http://10.160.0.12:8080}" KEYCLOAK_REALM="${KEYCLOAK_REALM:-master}" KEYCLOAK_CLIENT_ID="${KEYCLOAK_CLIENT_ID_PORTAL:-portal-client}" KEYCLOAK_CLIENT_SECRET="${KEYCLOAK_CLIENT_SECRET_PORTAL:-}" NEXTAUTH_SECRET="${NEXTAUTH_SECRET:-$(openssl rand -base64 32)}" NODE_VERSION="18" # SSH function ssh_r630_01() { ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 root@"$PROXMOX_HOST" "$@" } # Execute command in container exec_container() { ssh_r630_01 "pct exec $VMID -- $*" } main() { echo "" log_info "=========================================" log_info "Sankofa Portal Deployment" log_info "=========================================" echo "" log_info "Container VMID: $VMID" log_info "Container IP: $CONTAINER_IP" echo "" # Check if container exists and is running log_info "Checking container status..." if ! ssh_r630_01 "pct status $VMID >/dev/null 2>&1"; then log_error "Container $VMID does not exist. Please run deploy-sankofa-r630-01.sh first." exit 1 fi local status=$(ssh_r630_01 "pct status $VMID" 2>/dev/null | awk '{print $2}' || echo "stopped") if [[ "$status" != "running" ]]; then log_info "Starting container $VMID..." ssh_r630_01 "pct start $VMID" sleep 5 fi log_success "Container is running" echo "" # Install Node.js log_info "Installing Node.js $NODE_VERSION..." exec_container bash -c "export DEBIAN_FRONTEND=noninteractive && \ curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION}.x | bash - && \ apt-get install -y -qq nodejs" # Install pnpm log_info "Installing pnpm..." exec_container bash -c "npm install -g pnpm" log_success "Node.js and pnpm installed" echo "" # Copy project files log_info "Copying Sankofa Portal project files..." if [[ ! -d "$SANKOFA_PROJECT/portal" ]]; then log_error "Sankofa portal project not found at $SANKOFA_PROJECT/portal" log_info "Please ensure the Sankofa project is available" exit 1 fi # Create app directory exec_container bash -c "mkdir -p /opt/sankofa-portal" # Copy portal directory log_info "Copying files to container..." ssh_r630_01 "pct push $VMID $SANKOFA_PROJECT/portal /opt/sankofa-portal --recursive" log_success "Project files copied" echo "" # Install dependencies log_info "Installing dependencies..." exec_container bash -c "cd /opt/sankofa-portal && pnpm install --frozen-lockfile" log_success "Dependencies installed" echo "" # Create environment file log_info "Creating environment configuration..." exec_container bash -c "cat > /opt/sankofa-portal/.env.local << EOF # Keycloak KEYCLOAK_URL=$KEYCLOAK_URL KEYCLOAK_REALM=$KEYCLOAK_REALM KEYCLOAK_CLIENT_ID=$KEYCLOAK_CLIENT_ID KEYCLOAK_CLIENT_SECRET=$KEYCLOAK_CLIENT_SECRET # API NEXT_PUBLIC_GRAPHQL_ENDPOINT=$API_URL NEXT_PUBLIC_GRAPHQL_WS_ENDPOINT=$API_WS_URL # NextAuth NEXTAUTH_URL=http://$CONTAINER_IP:3000 NEXTAUTH_SECRET=$NEXTAUTH_SECRET # Crossplane (if available) NEXT_PUBLIC_CROSSPLANE_API=${NEXT_PUBLIC_CROSSPLANE_API:-http://crossplane.sankofa.nexus} NEXT_PUBLIC_ARGOCD_URL=${NEXT_PUBLIC_ARGOCD_URL:-http://argocd.sankofa.nexus} NEXT_PUBLIC_GRAFANA_URL=${NEXT_PUBLIC_GRAFANA_URL:-http://grafana.sankofa.nexus} NEXT_PUBLIC_LOKI_URL=${NEXT_PUBLIC_LOKI_URL:-http://loki.sankofa.nexus:3100} # App NEXT_PUBLIC_APP_URL=http://$CONTAINER_IP:3000 NODE_ENV=production EOF" log_success "Environment configured" echo "" # Build Portal log_info "Building Portal (this may take several minutes)..." exec_container bash -c "cd /opt/sankofa-portal && pnpm build" log_success "Portal built" echo "" # Create systemd service log_info "Creating systemd service..." exec_container bash -c "cat > /etc/systemd/system/sankofa-portal.service << 'EOF' [Unit] Description=Sankofa Portal After=network.target [Service] Type=simple User=root WorkingDirectory=/opt/sankofa-portal Environment=\"NODE_ENV=production\" EnvironmentFile=/opt/sankofa-portal/.env.local ExecStart=/usr/bin/node /opt/sankofa-portal/node_modules/.bin/next start Restart=always RestartSec=10 StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target EOF" # Start service log_info "Starting Portal service..." exec_container bash -c "systemctl daemon-reload && \ systemctl enable sankofa-portal && \ systemctl start sankofa-portal" sleep 10 # Check service status if exec_container bash -c "systemctl is-active --quiet sankofa-portal"; then log_success "Portal service is running" else log_error "Portal service failed to start" exec_container bash -c "journalctl -u sankofa-portal -n 50 --no-pager" exit 1 fi echo "" # Test Portal log_info "Testing Portal..." sleep 5 if exec_container bash -c "curl -s -f http://localhost:3000 >/dev/null 2>&1"; then log_success "Portal is accessible" else log_warn "Portal may still be starting - check logs if issues persist" fi echo "" # Summary log_success "=========================================" log_success "Sankofa Portal Deployment Complete" log_success "=========================================" echo "" log_info "Portal Configuration:" echo " URL: http://$CONTAINER_IP:3000" echo " API: $API_URL" echo " Keycloak: $KEYCLOAK_URL" echo "" log_info "Next steps:" echo " 1. Verify Portal is accessible: curl http://$CONTAINER_IP:3000" echo " 2. Configure firewall rules if needed" echo " 3. Set up Cloudflare tunnels for external access" echo "" } main "$@"