#!/usr/bin/env bash # # EventBuzz production deploy # # Usage: # ./deploy.sh # backend + dashboard + visitor website + public web # ./deploy.sh backend # ./deploy.sh frontend # ./deploy.sh website # ./deploy.sh web # ./deploy.sh all # # Requirements: ssh, rsync, npm, aws CLI (profile stratawiztech) # set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SSH_KEY="${SSH_KEY:-$HOME/Documents/Keys/ravimac}" SSH_HOST="${SSH_HOST:-root@168.144.70.247}" BACKEND_REMOTE="${BACKEND_REMOTE:-/var/www/backend}" AWS_PROFILE="${AWS_PROFILE:-stratawiztech}" FRONTEND_DIR="$ROOT/frontend" EVENTBUZZ_DIR="$ROOT/eventbuzz" WEB_DIR="$ROOT/web" BACKEND_DIR="$ROOT/backend" S3_CONSOLE="s3://eventbuzzlive/console/" S3_WEBSITE="s3://eventbuzzlive/website/" S3_WEB="s3://eventbuzzlive/web/" # CloudFront distributions (console dashboard + visitor website + public web) CF_CONSOLE="${CF_CONSOLE:-E1QQM75X0JF0IU}" CF_WEBSITE="${CF_WEBSITE:-E3ORUQT7269RIM}" CF_WEB="${CF_WEB:-ETZS6Z42DG7I6}" log() { printf '\n\033[1;36m==>\033[0m %s\n' "$*"; } die() { printf '\033[1;31merror:\033[0m %s\n' "$*" >&2; exit 1; } ssh_cmd() { ssh -i "$SSH_KEY" -o StrictHostKeyChecking=accept-new "$SSH_HOST" "$@" } rsync_ssh() { rsync -avz -e "ssh -i $SSH_KEY -o StrictHostKeyChecking=accept-new" "$@" } invalidate_cloudfront() { local distribution_id="$1" local label="$2" log "CloudFront invalidation ($label) → $distribution_id /*" aws cloudfront create-invalidation \ --distribution-id "$distribution_id" \ --paths "/*" \ --profile "$AWS_PROFILE" \ --output text \ --query 'Invalidation.Id' } # Ensure dashboard / visitor builds use production API URLs (not localhost). apply_production_env() { log "Applying production env for dashboard (frontend/.env.production)" if [[ ! -f "$FRONTEND_DIR/.env.production" ]]; then die "Missing $FRONTEND_DIR/.env.production — create it with production VITE_* URLs." fi # If a local .env exists, show what we're overriding for clarity if [[ -f "$FRONTEND_DIR/.env" ]]; then grep -E '^VITE_API_URL=' "$FRONTEND_DIR/.env.production" || true fi log "Applying production env for visitor site (eventbuzz/.env.production)" if [[ ! -f "$EVENTBUZZ_DIR/.env.production" ]]; then die "Missing $EVENTBUZZ_DIR/.env.production — create it with production VITE_* URLs." fi grep -E '^VITE_API_BASE_URL=' "$EVENTBUZZ_DIR/.env.production" || true log "Applying production env for public web (web/.env.production)" if [[ ! -f "$WEB_DIR/.env.production" ]]; then die "Missing $WEB_DIR/.env.production — create it with production VITE_* URLs." fi grep -E '^VITE_(API_BASE_URL|PUBLIC_WEB_BASE)=' "$WEB_DIR/.env.production" || true } deploy_backend() { log "Deploying backend → $SSH_HOST:$BACKEND_REMOTE/" [[ -d "$BACKEND_DIR/src" ]] || die "Backend src folder not found at $BACKEND_DIR/src" [[ -f "$BACKEND_DIR/package.json" ]] || die "Backend package.json not found" [[ -f "$SSH_KEY" ]] || die "SSH key not found: $SSH_KEY" rsync_ssh --delete \ "$BACKEND_DIR/src/" \ "$SSH_HOST:$BACKEND_REMOTE/src/" log "Syncing package.json + package-lock.json" rsync_ssh \ "$BACKEND_DIR/package.json" \ "$BACKEND_DIR/package-lock.json" \ "$SSH_HOST:$BACKEND_REMOTE/" log "Installing dependencies + reloading API on server (pm2)" ssh_cmd "cd '$BACKEND_REMOTE' && npm ci --omit=dev && (pm2 reload all || pm2 restart all || echo 'pm2 reload skipped — run manually on server')" } deploy_frontend() { log "Building dashboard (console) for production" apply_production_env cd "$FRONTEND_DIR" npm run build log "Uploading dashboard dist → $S3_CONSOLE" aws s3 rm "$S3_CONSOLE" --recursive --profile "$AWS_PROFILE" aws s3 sync "$FRONTEND_DIR/dist" "$S3_CONSOLE" --profile "$AWS_PROFILE" invalidate_cloudfront "$CF_CONSOLE" "console" log "Dashboard deploy complete" } deploy_website() { log "Building visitor website for production" apply_production_env cd "$EVENTBUZZ_DIR" npm run build log "Uploading visitor site dist → $S3_WEBSITE" aws s3 rm "$S3_WEBSITE" --recursive --profile "$AWS_PROFILE" aws s3 sync "$EVENTBUZZ_DIR/dist" "$S3_WEBSITE" --profile "$AWS_PROFILE" invalidate_cloudfront "$CF_WEBSITE" "website" log "Visitor website deploy complete" } deploy_web() { log "Building public web app for production" apply_production_env cd "$WEB_DIR" npm run build log "Uploading public web dist → $S3_WEB" aws s3 rm "$S3_WEB" --recursive --profile "$AWS_PROFILE" aws s3 sync "$WEB_DIR/dist" "$S3_WEB" --profile "$AWS_PROFILE" invalidate_cloudfront "$CF_WEB" "web" log "Public web deploy complete" } usage() { cat <