cinema-studio-pro/deploy.sh
2026-02-27 20:33:26 +05:30

281 lines
12 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
################################################################################
# Lux Studio — Production Deployment Script
#
# Usage:
# cd /opt/cinema-studio-pro
# sudo ./deploy.sh
#
# What it does:
# 1. Builds the React frontend using frontend/.env.production
# 2. Deploys built files → /var/www/html/lux-studio/
# 3. Deploys backend PHP → /var/www/html/lux-studio/api/
# 4. Verifies the deployment
#
# Apache serves PHP directly — no systemd service or proxy needed.
# Apache configuration (AllowOverride, modules) is managed separately by the operator.
# The backend .env on the server is never overwritten (preserves API keys).
################################################################################
set -e
# ─── Colors ───────────────────────────────────────────────────────────────────
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# ─── Configuration ─────────────────────────────────────────────────────────────
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
FRONTEND_SRC="$SCRIPT_DIR/frontend"
BACKEND_SRC="$SCRIPT_DIR/backend"
WEB_ROOT="/var/www/html/lux-studio"
API_ROOT="$WEB_ROOT/api"
# PHP files that must never be deployed to the server
SKIP_PHP=("test.php" "config.example.php")
# ─── Helper functions ─────────────────────────────────────────────────────────
step() { echo ""; echo -e "${YELLOW}[$1] $2...${NC}"; }
ok() { echo -e "${GREEN}$1${NC}"; }
warn() { echo -e "${YELLOW}$1${NC}"; }
fail() { echo -e "${RED} Error: $1${NC}"; exit 1; }
# ─── Header ───────────────────────────────────────────────────────────────────
echo ""
echo -e "${BLUE}========================================"
echo -e " Lux Studio — Production Deployment"
echo -e "========================================${NC}"
echo ""
echo " Source: $SCRIPT_DIR"
echo " Frontend: $WEB_ROOT"
echo " Backend: $API_ROOT"
echo ""
# ─── Root check ───────────────────────────────────────────────────────────────
[[ $EUID -ne 0 ]] && fail "This script must be run as root. Use: sudo ./deploy.sh"
# ─────────────────────────────────────────────────────────────────────────────
step "1/6" "Preflight checks"
# ─────────────────────────────────────────────────────────────────────────────
[ -d "$FRONTEND_SRC" ] || fail "frontend/ directory not found in $SCRIPT_DIR"
[ -d "$BACKEND_SRC" ] || fail "backend/ directory not found in $SCRIPT_DIR"
[ -f "$FRONTEND_SRC/.env.production" ] \
|| fail "frontend/.env.production not found — cannot build for production"
[ -f "$BACKEND_SRC/.env.production" ] \
|| warn "backend/.env.production not found — /api/.env will not be created automatically"
# Check required system commands
for cmd in php node npm; do
command -v "$cmd" &>/dev/null \
&& ok "$cmd: $(command -v $cmd)" \
|| fail "$cmd is not installed"
done
ok "Preflight passed"
# ─────────────────────────────────────────────────────────────────────────────
step "2/6" "Building frontend"
# ─────────────────────────────────────────────────────────────────────────────
cd "$FRONTEND_SRC"
# Always use .env.production for production builds — never use a cached .env
cp .env.production .env
ok "frontend/.env overwritten from .env.production"
# Install npm dependencies if node_modules is absent or package.json changed
echo " Checking npm dependencies..."
npm install --silent
ok "npm dependencies ready"
echo " Building (this may take 3060 seconds)..."
npm run build
ok "Build complete → frontend/dist/"
# Confirm the correct API path was baked into the bundle
if grep -qo "lux-studio/api" dist/assets/*.js 2>/dev/null; then
ok "API URL verified in bundle: lux-studio/api"
else
fail "Bundle does not contain 'lux-studio/api'. Check VITE_API_URL in frontend/.env.production"
fi
cd "$SCRIPT_DIR"
# ─────────────────────────────────────────────────────────────────────────────
step "3/6" "Deploying frontend to $WEB_ROOT"
# ─────────────────────────────────────────────────────────────────────────────
mkdir -p "$WEB_ROOT"
# Delete old assets/ first — Vite produces differently hash-named files each
# build. Leaving old files causes stale JS to be served.
if [ -d "$WEB_ROOT/assets" ]; then
rm -rf "$WEB_ROOT/assets"
ok "Old assets/ removed (hash names change each build)"
fi
# Copy built output
cp "$FRONTEND_SRC/dist/index.html" "$WEB_ROOT/index.html"
cp -r "$FRONTEND_SRC/dist/assets" "$WEB_ROOT/assets"
ok "index.html and assets/ deployed"
# Copy static public assets (logos, favicon — not always present in all builds)
for item in LUX_STUDIO_LOGO.svg LUX_STUDIO_LOGO.png; do
src="$FRONTEND_SRC/dist/$item"
[ -e "$src" ] && cp "$src" "$WEB_ROOT/$item"
done
ok "Static assets deployed (LUX_STUDIO_LOGO.svg, LUX_STUDIO_LOGO.png)"
# .htaccess is NOT copied into dist/ by Vite — must be taken from source
if [ -f "$FRONTEND_SRC/.htaccess" ]; then
cp "$FRONTEND_SRC/.htaccess" "$WEB_ROOT/.htaccess"
ok ".htaccess deployed from frontend/.htaccess (not from dist/)"
else
warn "frontend/.htaccess not found — React Router deep links will break"
fi
chown -R www-data:www-data "$WEB_ROOT"
chmod -R 755 "$WEB_ROOT"
ok "Permissions set (www-data:www-data, 755)"
# ─────────────────────────────────────────────────────────────────────────────
step "4/6" "Deploying backend PHP to $API_ROOT"
# ─────────────────────────────────────────────────────────────────────────────
mkdir -p "$API_ROOT"
# Copy all .php files from backend/ except those in SKIP_PHP
PHP_COUNT=0
for php_file in "$BACKEND_SRC"/*.php; do
filename=$(basename "$php_file")
skip=false
for skip_name in "${SKIP_PHP[@]}"; do
[ "$filename" = "$skip_name" ] && skip=true && break
done
if [ "$skip" = false ]; then
cp "$php_file" "$API_ROOT/$filename"
PHP_COUNT=$((PHP_COUNT + 1))
fi
done
ok "$PHP_COUNT PHP files deployed (skipped: ${SKIP_PHP[*]})"
# Copy backend .htaccess (security rules, blocks .env/vendor/direct class access)
if [ -f "$BACKEND_SRC/.htaccess" ]; then
cp "$BACKEND_SRC/.htaccess" "$API_ROOT/.htaccess"
ok "Backend .htaccess deployed"
fi
# ── .env handling ──────────────────────────────────────────────────────────────
# The production .env contains the real GEMINI_API_KEY.
# NEVER overwrite it — only create it if it does not exist yet.
if [ -f "$API_ROOT/.env" ]; then
ok "/api/.env already exists — not overwritten (production secrets preserved)"
else
if [ -f "$BACKEND_SRC/.env.production" ]; then
cp "$BACKEND_SRC/.env.production" "$API_ROOT/.env"
ok "Created /api/.env from backend/.env.production"
echo ""
warn "ACTION REQUIRED: Verify GEMINI_API_KEY and FRONTEND_URL in /api/.env:"
warn " sudo nano $API_ROOT/.env"
echo ""
else
warn "backend/.env.production not found — /api/.env was NOT created"
warn "Create it manually: sudo nano $API_ROOT/.env"
warn "Required keys: GEMINI_API_KEY, FRONTEND_URL, SSO_ENABLED"
fi
fi
# Create uploads directory (PHP writes generated images/videos here)
mkdir -p "$API_ROOT/uploads/sessions"
# Set ownership before chmod so chmod applies correctly
chown -R www-data:www-data "$API_ROOT"
chmod -R 755 "$API_ROOT"
# www-data must be able to write generated files
chmod -R 777 "$API_ROOT/uploads"
ok "Permissions set (uploads/: 777 for www-data writes)"
# ─────────────────────────────────────────────────────────────────────────────
step "5/6" "Verifying deployment"
# ─────────────────────────────────────────────────────────────────────────────
ERRORS=0
check() {
# $1 = path to check, $2 = label, $3 = "warn" (non-fatal) or empty (fatal)
if [ -e "$1" ]; then
ok "$2"
elif [ "$3" = "warn" ]; then
warn "$2 not found"
else
echo -e "${RED}$2 — MISSING${NC}"
ERRORS=$((ERRORS+1))
fi
}
# Frontend
check "$WEB_ROOT/index.html" "index.html"
check "$WEB_ROOT/assets" "assets/ directory"
check "$WEB_ROOT/.htaccess" ".htaccess (frontend)" warn
# Backend
check "$API_ROOT/api.php" "api.php"
check "$API_ROOT/AuthMiddleware.php" "AuthMiddleware.php ← api.php requires this"
check "$API_ROOT/video_api.php" "video_api.php"
check "$API_ROOT/enhance_prompt.php" "enhance_prompt.php"
check "$API_ROOT/.htaccess" ".htaccess (backend)"
check "$API_ROOT/uploads/sessions" "uploads/sessions/"
if [ -f "$API_ROOT/.env" ]; then
ok "/api/.env present"
else
echo -e "${RED} ✗ /api/.env MISSING — all API calls will fail without it${NC}"
ERRORS=$((ERRORS+1))
fi
# Confirm bundle has the right API URL
if grep -qo "lux-studio/api" "$WEB_ROOT"/assets/*.js 2>/dev/null; then
ok "Bundle contains correct API path (lux-studio/api)"
else
warn "Could not verify API path in deployed bundle"
fi
# ─────────────────────────────────────────────────────────────────────────────
step "6/6" "Summary"
# ─────────────────────────────────────────────────────────────────────────────
echo ""
echo -e "${BLUE} Deployed:${NC}"
echo " Frontend → $WEB_ROOT"
echo " Backend → $API_ROOT"
echo ""
echo -e "${BLUE} Live URL:${NC}"
echo " https://ai-sandbox.oliver.solutions/lux-studio/"
echo ""
echo -e "${BLUE} Useful commands:${NC}"
echo " Check .env: sudo cat $API_ROOT/.env"
echo " Apache errors: sudo tail -f /var/log/apache2/error.log"
echo " Reload Apache: sudo systemctl reload apache2"
echo " Re-deploy: cd $SCRIPT_DIR && sudo ./deploy.sh"
echo ""
echo -e "${BLUE} Test checklist:${NC}"
echo " 1. Hard refresh in browser: Ctrl + Shift + R"
echo " 2. F12 → Network: API calls go to /lux-studio/api/ (not /lux-studio-back/)"
echo " 3. No 404 errors in the Network tab"
echo " 4. Create a project and generate an image with a 10+ word prompt"
echo ""
if [ $ERRORS -gt 0 ]; then
echo -e "${YELLOW}$ERRORS check(s) failed — review the output above before testing${NC}"
echo ""
exit 1
else
echo -e "${GREEN} ✓ All checks passed — deployment successful!${NC}"
echo ""
fi