512 lines
16 KiB
Bash
512 lines
16 KiB
Bash
#!/bin/bash
|
|
|
|
################################################################################
|
|
# Lux Studio Full Deployment Script
|
|
# Purpose: Automated deployment of Lux Studio (backend + frontend)
|
|
# Usage: Place entire project in /opt/lux-studio-back/ and run: sudo ./deploy.sh
|
|
################################################################################
|
|
|
|
set -e # Exit on any error
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Configuration
|
|
PROJECT_DIR="/opt/lux-studio-back"
|
|
FRONTEND_DIR="/var/www/html/lux-studio"
|
|
SERVICE_NAME="lux-studio-backend"
|
|
SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"
|
|
APACHE_CONF="/etc/apache2/apache2.conf"
|
|
BACKEND_PORT=5015
|
|
|
|
echo -e "${BLUE}========================================${NC}"
|
|
echo -e "${BLUE} Lux Studio Full Deployment Script${NC}"
|
|
echo -e "${BLUE}========================================${NC}"
|
|
echo ""
|
|
|
|
# Check if running as root
|
|
if [[ $EUID -ne 0 ]]; then
|
|
echo -e "${RED}Error: This script must be run as root${NC}"
|
|
echo "Please run: sudo $0"
|
|
exit 1
|
|
fi
|
|
|
|
# Check if running from correct directory
|
|
CURRENT_DIR=$(pwd)
|
|
if [ "$CURRENT_DIR" != "$PROJECT_DIR" ]; then
|
|
echo -e "${YELLOW}⚠ Warning: Not running from $PROJECT_DIR${NC}"
|
|
echo "Current directory: $CURRENT_DIR"
|
|
echo ""
|
|
fi
|
|
|
|
echo -e "${YELLOW}[1/15] Checking project structure...${NC}"
|
|
|
|
# Check if backend directory exists
|
|
if [ ! -d "$PROJECT_DIR" ]; then
|
|
echo -e "${RED}Error: Project directory $PROJECT_DIR does not exist${NC}"
|
|
echo "Please upload the entire project to $PROJECT_DIR first"
|
|
exit 1
|
|
fi
|
|
echo -e "${GREEN} ✓ Project directory exists${NC}"
|
|
|
|
# Check if backend files exist
|
|
if [ ! -f "$PROJECT_DIR/api.php" ]; then
|
|
echo -e "${RED}Error: Backend files not found in $PROJECT_DIR${NC}"
|
|
echo "Please ensure backend PHP files are in $PROJECT_DIR"
|
|
exit 1
|
|
fi
|
|
echo -e "${GREEN} ✓ Backend files found${NC}"
|
|
|
|
# Check if frontend directory exists in project
|
|
FRONTEND_SOURCE="$PROJECT_DIR/frontend"
|
|
HAS_FRONTEND=false
|
|
if [ -d "$FRONTEND_SOURCE" ]; then
|
|
echo -e "${GREEN} ✓ Frontend directory found (will build and deploy)${NC}"
|
|
HAS_FRONTEND=true
|
|
else
|
|
echo -e "${YELLOW} ⚠ Frontend directory not found (backend-only deployment)${NC}"
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${YELLOW}[2/15] Checking system requirements...${NC}"
|
|
|
|
# Check PHP
|
|
if ! command -v php &> /dev/null; then
|
|
echo -e "${RED}Error: PHP is not installed${NC}"
|
|
exit 1
|
|
fi
|
|
PHP_VERSION=$(php -v | head -n 1 | cut -d " " -f 2 | cut -d "." -f 1-2)
|
|
echo -e "${GREEN} ✓ PHP $PHP_VERSION installed${NC}"
|
|
|
|
# Check Composer
|
|
if ! command -v composer &> /dev/null; then
|
|
echo -e "${YELLOW} ⚠ Composer not found, installing...${NC}"
|
|
cd ~
|
|
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
|
|
php composer-setup.php --quiet --install-dir=/usr/local/bin --filename=composer
|
|
php -r "unlink('composer-setup.php');"
|
|
echo -e "${GREEN} ✓ Composer installed${NC}"
|
|
else
|
|
COMPOSER_VERSION=$(composer --version | head -n 1 | cut -d " " -f 3)
|
|
echo -e "${GREEN} ✓ Composer $COMPOSER_VERSION installed${NC}"
|
|
fi
|
|
|
|
# Check Apache
|
|
if ! command -v apache2 &> /dev/null; then
|
|
echo -e "${RED}Error: Apache is not installed${NC}"
|
|
exit 1
|
|
fi
|
|
echo -e "${GREEN} ✓ Apache installed${NC}"
|
|
|
|
# Check Node.js if frontend exists
|
|
if [ "$HAS_FRONTEND" = true ]; then
|
|
if ! command -v node &> /dev/null; then
|
|
echo -e "${YELLOW} ⚠ Node.js not found, installing...${NC}"
|
|
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
|
|
apt-get install -y nodejs
|
|
echo -e "${GREEN} ✓ Node.js installed${NC}"
|
|
else
|
|
NODE_VERSION=$(node -v)
|
|
echo -e "${GREEN} ✓ Node.js $NODE_VERSION installed${NC}"
|
|
fi
|
|
|
|
if ! command -v npm &> /dev/null; then
|
|
echo -e "${RED}Error: npm is not installed${NC}"
|
|
exit 1
|
|
fi
|
|
NPM_VERSION=$(npm -v)
|
|
echo -e "${GREEN} ✓ npm $NPM_VERSION installed${NC}"
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${YELLOW}[3/15] Installing backend dependencies...${NC}"
|
|
|
|
cd "$PROJECT_DIR"
|
|
|
|
# Install Composer dependencies
|
|
if [ ! -d "vendor" ]; then
|
|
echo " Installing PHP dependencies..."
|
|
sudo -u www-data composer install --no-dev --optimize-autoloader
|
|
echo -e "${GREEN} ✓ PHP dependencies installed${NC}"
|
|
else
|
|
echo -e "${GREEN} ✓ PHP dependencies already installed${NC}"
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${YELLOW}[4/15] Configuring backend environment...${NC}"
|
|
|
|
# Create .env if not exists
|
|
if [ ! -f "$PROJECT_DIR/.env" ]; then
|
|
if [ -f "$PROJECT_DIR/.env.production" ]; then
|
|
cp "$PROJECT_DIR/.env.production" "$PROJECT_DIR/.env"
|
|
echo -e "${GREEN} ✓ Created .env from .env.production${NC}"
|
|
echo -e "${GREEN} ✓ Production settings applied${NC}"
|
|
else
|
|
echo -e "${RED} Error: .env.production not found${NC}"
|
|
echo -e "${YELLOW} Please ensure backend/.env.production exists${NC}"
|
|
exit 1
|
|
fi
|
|
else
|
|
echo -e "${GREEN} ✓ .env file exists${NC}"
|
|
echo -e "${YELLOW} ⚠ Using existing .env (not overwriting)${NC}"
|
|
fi
|
|
|
|
# Create uploads directory
|
|
mkdir -p "$PROJECT_DIR/uploads/sessions"
|
|
echo -e "${GREEN} ✓ Uploads directory created${NC}"
|
|
|
|
# Set backend permissions
|
|
chown -R www-data:www-data "$PROJECT_DIR"
|
|
chmod -R 755 "$PROJECT_DIR"
|
|
chmod -R 777 "$PROJECT_DIR/uploads"
|
|
echo -e "${GREEN} ✓ Backend permissions set${NC}"
|
|
|
|
echo ""
|
|
echo -e "${YELLOW}[5/15] Building and deploying frontend...${NC}"
|
|
|
|
if [ "$HAS_FRONTEND" = true ]; then
|
|
cd "$FRONTEND_SOURCE"
|
|
|
|
# Check for production .env
|
|
if [ ! -f ".env" ]; then
|
|
if [ -f ".env.production" ]; then
|
|
echo " Creating frontend .env from .env.production..."
|
|
cp ".env.production" ".env"
|
|
echo -e "${GREEN} ✓ Created frontend .env with production settings${NC}"
|
|
else
|
|
echo -e "${RED} Error: .env.production not found${NC}"
|
|
echo -e "${YELLOW} Please ensure frontend/.env.production exists${NC}"
|
|
exit 1
|
|
fi
|
|
else
|
|
echo -e "${GREEN} ✓ Frontend .env exists${NC}"
|
|
echo -e "${YELLOW} ⚠ Using existing .env (not overwriting)${NC}"
|
|
fi
|
|
|
|
# Install npm dependencies
|
|
echo " Installing npm dependencies..."
|
|
npm install --silent
|
|
echo -e "${GREEN} ✓ npm dependencies installed${NC}"
|
|
|
|
# Build frontend
|
|
echo " Building frontend (this may take 30-60 seconds)..."
|
|
npm run build
|
|
echo -e "${GREEN} ✓ Frontend built successfully${NC}"
|
|
|
|
# Deploy frontend
|
|
echo " Deploying frontend to $FRONTEND_DIR..."
|
|
mkdir -p "$FRONTEND_DIR"
|
|
rm -rf "$FRONTEND_DIR"/*
|
|
cp -r dist/* "$FRONTEND_DIR/"
|
|
|
|
# Copy .htaccess if exists
|
|
if [ -f ".htaccess" ]; then
|
|
cp ".htaccess" "$FRONTEND_DIR/"
|
|
echo -e "${GREEN} ✓ .htaccess copied${NC}"
|
|
fi
|
|
|
|
# Set frontend permissions
|
|
chown -R www-data:www-data "$FRONTEND_DIR"
|
|
chmod -R 755 "$FRONTEND_DIR"
|
|
echo -e "${GREEN} ✓ Frontend deployed to $FRONTEND_DIR${NC}"
|
|
|
|
# Verify deployment
|
|
if [ -f "$FRONTEND_DIR/index.html" ]; then
|
|
echo -e "${GREEN} ✓ Frontend deployment verified${NC}"
|
|
else
|
|
echo -e "${RED} Error: Frontend deployment failed${NC}"
|
|
exit 1
|
|
fi
|
|
else
|
|
echo -e "${YELLOW} ⚠ Skipping frontend build (no frontend directory)${NC}"
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${YELLOW}[6/15] Setting up systemd service...${NC}"
|
|
|
|
# Check if service file exists in project
|
|
if [ -f "$PROJECT_DIR/lux-studio-backend.service" ]; then
|
|
if [ ! -f "$SERVICE_FILE" ] || [ "$PROJECT_DIR/lux-studio-backend.service" -nt "$SERVICE_FILE" ]; then
|
|
echo " Copying service file to systemd..."
|
|
cp "$PROJECT_DIR/lux-studio-backend.service" "$SERVICE_FILE"
|
|
chmod 644 "$SERVICE_FILE"
|
|
echo -e "${GREEN} ✓ Service file installed${NC}"
|
|
else
|
|
echo -e "${GREEN} ✓ Service file already up to date${NC}"
|
|
fi
|
|
else
|
|
if [ ! -f "$SERVICE_FILE" ]; then
|
|
echo -e "${RED} Error: Service file not found${NC}"
|
|
echo " Please ensure lux-studio-backend.service exists in project root"
|
|
exit 1
|
|
fi
|
|
echo -e "${GREEN} ✓ Service file exists${NC}"
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${YELLOW}[7/15] Configuring Apache...${NC}"
|
|
|
|
# Enable required modules
|
|
echo " Enabling Apache modules..."
|
|
a2enmod rewrite proxy proxy_http headers ssl 2>/dev/null || true
|
|
echo -e "${GREEN} ✓ Apache modules enabled${NC}"
|
|
|
|
# Check if Apache config already has Lux Studio configuration
|
|
if grep -q "lux-studio-back" "$APACHE_CONF"; then
|
|
echo -e "${GREEN} ✓ Apache configuration already present${NC}"
|
|
else
|
|
echo " Adding Lux Studio configuration to Apache..."
|
|
|
|
# Create backup
|
|
cp "$APACHE_CONF" "${APACHE_CONF}.backup-$(date +%Y%m%d-%H%M%S)"
|
|
echo -e "${GREEN} ✓ Apache config backed up${NC}"
|
|
|
|
# Check if apache config file exists in project
|
|
if [ -f "$PROJECT_DIR/lux-studio-apache.conf" ]; then
|
|
# Add configuration
|
|
cat >> "$APACHE_CONF" << 'EOF'
|
|
|
|
# ==============================================================================
|
|
# LUX STUDIO CONFIGURATION
|
|
# ==============================================================================
|
|
|
|
# Backend API Proxy
|
|
ProxyPass /lux-studio-back/ http://localhost:5015/
|
|
ProxyPassReverse /lux-studio-back/ http://localhost:5015/
|
|
|
|
# Frontend Directory
|
|
<Directory /var/www/html/lux-studio>
|
|
Options -Indexes +FollowSymLinks
|
|
AllowOverride All
|
|
Require all granted
|
|
</Directory>
|
|
|
|
# Security - Block backend source access
|
|
<Directory /opt/lux-studio-back>
|
|
Require all denied
|
|
</Directory>
|
|
|
|
# CORS Headers
|
|
<Location /lux-studio-back>
|
|
Header set Access-Control-Allow-Origin "https://ai-sandbox.oliver.solutions"
|
|
Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
|
|
Header set Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With"
|
|
Header set Access-Control-Allow-Credentials "true"
|
|
</Location>
|
|
|
|
# ==============================================================================
|
|
# END LUX STUDIO CONFIGURATION
|
|
# ==============================================================================
|
|
EOF
|
|
echo -e "${GREEN} ✓ Apache configuration added${NC}"
|
|
else
|
|
echo -e "${YELLOW} ⚠ Apache config file not found, please add manually${NC}"
|
|
echo " Add the contents of lux-studio-apache.conf to $APACHE_CONF"
|
|
fi
|
|
fi
|
|
|
|
# Test Apache configuration
|
|
echo " Testing Apache configuration..."
|
|
if apache2ctl configtest 2>&1 | grep -q "Syntax OK"; then
|
|
echo -e "${GREEN} ✓ Apache configuration valid${NC}"
|
|
else
|
|
echo -e "${RED} Error: Apache configuration invalid${NC}"
|
|
apache2ctl configtest
|
|
exit 1
|
|
fi
|
|
|
|
# Reload Apache
|
|
echo " Reloading Apache..."
|
|
systemctl reload apache2
|
|
echo -e "${GREEN} ✓ Apache reloaded${NC}"
|
|
|
|
echo ""
|
|
echo -e "${YELLOW}[8/15] Checking for port conflicts...${NC}"
|
|
|
|
if lsof -Pi :$BACKEND_PORT -sTCP:LISTEN -t >/dev/null 2>&1 ; then
|
|
echo -e "${YELLOW} ⚠ Port $BACKEND_PORT is already in use${NC}"
|
|
PID=$(lsof -Pi :$BACKEND_PORT -sTCP:LISTEN -t)
|
|
PROCESS=$(ps -p $PID -o comm=)
|
|
echo " Process: $PROCESS (PID: $PID)"
|
|
|
|
if [[ $PROCESS == *"php"* ]]; then
|
|
echo " Stopping existing PHP service..."
|
|
systemctl stop $SERVICE_NAME 2>/dev/null || true
|
|
sleep 2
|
|
|
|
# Force kill if still running
|
|
if lsof -Pi :$BACKEND_PORT -sTCP:LISTEN -t >/dev/null 2>&1 ; then
|
|
echo " Force killing process on port $BACKEND_PORT..."
|
|
kill -9 $PID 2>/dev/null || true
|
|
sleep 1
|
|
fi
|
|
echo -e "${GREEN} ✓ Port cleared${NC}"
|
|
else
|
|
echo -e "${RED} Error: Port $BACKEND_PORT is used by another service${NC}"
|
|
exit 1
|
|
fi
|
|
else
|
|
echo -e "${GREEN} ✓ Port $BACKEND_PORT is available${NC}"
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${YELLOW}[9/15] Starting backend service...${NC}"
|
|
|
|
systemctl daemon-reload
|
|
echo -e "${GREEN} ✓ Systemd daemon reloaded${NC}"
|
|
|
|
systemctl enable $SERVICE_NAME
|
|
echo -e "${GREEN} ✓ Service enabled (auto-start on boot)${NC}"
|
|
|
|
systemctl start $SERVICE_NAME
|
|
echo " Waiting for service to initialize..."
|
|
sleep 3
|
|
|
|
# Check if service started
|
|
if systemctl is-active --quiet $SERVICE_NAME; then
|
|
echo -e "${GREEN} ✓ Backend service started${NC}"
|
|
else
|
|
echo -e "${RED} Error: Service failed to start${NC}"
|
|
echo " Checking logs:"
|
|
journalctl -u $SERVICE_NAME -n 20 --no-pager
|
|
exit 1
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${YELLOW}[10/15] Verifying backend service...${NC}"
|
|
|
|
# Check port is listening
|
|
if lsof -Pi :$BACKEND_PORT -sTCP:LISTEN -t >/dev/null 2>&1 ; then
|
|
echo -e "${GREEN} ✓ Backend listening on port $BACKEND_PORT${NC}"
|
|
else
|
|
echo -e "${RED} Error: Backend not listening on port $BACKEND_PORT${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Test backend directly
|
|
echo " Testing backend API..."
|
|
if curl -f -s http://localhost:$BACKEND_PORT/server-check.php > /dev/null 2>&1; then
|
|
echo -e "${GREEN} ✓ Backend API responding${NC}"
|
|
else
|
|
echo -e "${YELLOW} ⚠ Backend API test failed (might be normal)${NC}"
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${YELLOW}[11/15] Testing Apache proxy...${NC}"
|
|
|
|
# Get server domain from Apache config or use localhost
|
|
DOMAIN=$(grep -m 1 "ServerName" "$APACHE_CONF" | awk '{print $2}')
|
|
if [ -z "$DOMAIN" ]; then
|
|
DOMAIN="localhost"
|
|
fi
|
|
|
|
echo " Testing proxy to backend..."
|
|
if curl -f -s -k "https://$DOMAIN/lux-studio-back/server-check.php" > /dev/null 2>&1; then
|
|
echo -e "${GREEN} ✓ Apache proxy working${NC}"
|
|
else
|
|
echo -e "${YELLOW} ⚠ Proxy test failed (might need manual verification)${NC}"
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${YELLOW}[12/15] Verifying frontend deployment...${NC}"
|
|
|
|
if [ -f "$FRONTEND_DIR/index.html" ]; then
|
|
echo -e "${GREEN} ✓ Frontend index.html exists${NC}"
|
|
else
|
|
echo -e "${YELLOW} ⚠ Frontend index.html not found${NC}"
|
|
fi
|
|
|
|
if [ -d "$FRONTEND_DIR/assets" ]; then
|
|
ASSET_COUNT=$(ls -1 "$FRONTEND_DIR/assets" 2>/dev/null | wc -l)
|
|
echo -e "${GREEN} ✓ Frontend assets directory exists ($ASSET_COUNT files)${NC}"
|
|
else
|
|
echo -e "${YELLOW} ⚠ Frontend assets directory not found${NC}"
|
|
fi
|
|
|
|
if [ -f "$FRONTEND_DIR/LUX_STUDIO_LOGO.svg" ]; then
|
|
echo -e "${GREEN} ✓ Logo file exists${NC}"
|
|
else
|
|
echo -e "${YELLOW} ⚠ Logo file not found${NC}"
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${YELLOW}[13/15] Checking API paths in build...${NC}"
|
|
|
|
if [ -d "$FRONTEND_DIR/assets" ]; then
|
|
# Check if built files use correct API path
|
|
if grep -r "lux-studio-back" "$FRONTEND_DIR/assets"/*.js >/dev/null 2>&1; then
|
|
echo -e "${GREEN} ✓ Frontend uses correct API path (/lux-studio-back/)${NC}"
|
|
else
|
|
echo -e "${YELLOW} ⚠ Could not verify API path in frontend build${NC}"
|
|
fi
|
|
|
|
# Check for old API path
|
|
if grep -r '"/api/api.php"' "$FRONTEND_DIR/assets"/*.js >/dev/null 2>&1; then
|
|
echo -e "${RED} ✗ Frontend still uses old API path (/api/)${NC}"
|
|
echo " This will cause 404 errors. Rebuild frontend with correct configuration."
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${YELLOW}[14/15] Service status...${NC}"
|
|
systemctl status $SERVICE_NAME --no-pager | head -10
|
|
|
|
echo ""
|
|
echo -e "${YELLOW}[15/15] Final health checks...${NC}"
|
|
|
|
# Summary
|
|
BACKEND_OK="✓"
|
|
FRONTEND_OK="✓"
|
|
PROXY_OK="✓"
|
|
|
|
if ! systemctl is-active --quiet $SERVICE_NAME; then
|
|
BACKEND_OK="✗"
|
|
fi
|
|
|
|
if [ ! -f "$FRONTEND_DIR/index.html" ]; then
|
|
FRONTEND_OK="✗"
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${GREEN}========================================${NC}"
|
|
echo -e "${GREEN} Deployment Complete!${NC}"
|
|
echo -e "${GREEN}========================================${NC}"
|
|
echo ""
|
|
echo -e "${BLUE}Status Summary:${NC}"
|
|
echo -e " Backend Service: ${BACKEND_OK}"
|
|
echo -e " Frontend Files: ${FRONTEND_OK}"
|
|
echo -e " Apache Proxy: ${PROXY_OK}"
|
|
echo ""
|
|
echo -e "${BLUE}Deployment Information:${NC}"
|
|
echo " Backend Port: $BACKEND_PORT"
|
|
echo " Backend Dir: $PROJECT_DIR"
|
|
echo " Frontend Dir: $FRONTEND_DIR"
|
|
echo " Service Name: $SERVICE_NAME"
|
|
echo ""
|
|
echo -e "${BLUE}Access URLs:${NC}"
|
|
echo " Frontend: https://ai-sandbox.oliver.solutions/lux-studio/"
|
|
echo " Backend: https://ai-sandbox.oliver.solutions/lux-studio-back/"
|
|
echo ""
|
|
echo -e "${BLUE}Service Commands:${NC}"
|
|
echo " Status: sudo systemctl status $SERVICE_NAME"
|
|
echo " Logs: sudo journalctl -u $SERVICE_NAME -f"
|
|
echo " Restart: sudo systemctl restart $SERVICE_NAME"
|
|
echo ""
|
|
echo -e "${BLUE}Testing:${NC}"
|
|
echo " 1. Clear browser cache (Ctrl+Shift+Delete)"
|
|
echo " 2. Visit: https://ai-sandbox.oliver.solutions/lux-studio/"
|
|
echo " 3. Login with Microsoft SSO"
|
|
echo " 4. Create a project and test image/video generation"
|
|
echo ""
|
|
|
|
if [ "$BACKEND_OK" = "✓" ] && [ "$FRONTEND_OK" = "✓" ]; then
|
|
echo -e "${GREEN}✓ Deployment successful!${NC}"
|
|
else
|
|
echo -e "${YELLOW}⚠ Deployment completed with warnings. Please review above.${NC}"
|
|
fi
|
|
|
|
echo ""
|