#!/bin/bash ################################################################################ # VidRip Production Startup Script ################################################################################ # This script builds and runs the VidRip service in production mode. # It handles dependency checks, builds both frontend and backend, and starts # the backend server with proper process management. ################################################################################ set -e # Exit on error set -u # Exit on undefined variable # Parse command line arguments USE_SYSTEMD=false while [[ $# -gt 0 ]]; do case $1 in --systemd) USE_SYSTEMD=true shift ;; --help|-h) echo "Usage: $0 [OPTIONS]" echo "" echo "Options:" echo " --systemd Use systemd service instead of nohup (requires sudo)" echo " --help Show this help message" exit 0 ;; *) echo "Unknown option: $1" echo "Use --help for usage information" exit 1 ;; esac done # Color codes for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Script directory WEB_ROOT="/var/www/vidrip" SCRIPT_DIR=$(pwd) echo -e "$SCRIPT_DIR" rm -rf "$WEB_ROOT/*" cd "$SCRIPT_DIR" # Configuration BACKEND_DIR="$SCRIPT_DIR/backend" FRONTEND_DIR="$SCRIPT_DIR/frontend" LOG_DIR="$SCRIPT_DIR/logs" PID_FILE="$SCRIPT_DIR/vidrip.pid" LOG_FILE="$LOG_DIR/vidrip.log" ERROR_LOG_FILE="$LOG_DIR/vidrip-error.log" ################################################################################ # Helper Functions ################################################################################ log_info() { echo -e "${BLUE}[INFO]${NC} $1" } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } check_command() { if ! command -v "$1" &> /dev/null; then log_error "$1 is not installed or not in PATH" return 1 fi log_success "$1 is installed" return 0 } cleanup_on_exit() { log_info "Cleaning up..." if [ -f "$PID_FILE" ]; then rm -f "$PID_FILE" fi } ################################################################################ # Pre-flight Checks ################################################################################ log_info "Starting VidRip production deployment..." echo "" log_info "Checking system requirements..." # Check for Node.js if ! check_command node; then log_error "Node.js is required but not installed" exit 1 fi NODE_VERSION=$(node --version | cut -d'v' -f2 | cut -d'.' -f1) if [ "$NODE_VERSION" -lt 18 ]; then log_error "Node.js version 18 or higher is required (found v$NODE_VERSION)" exit 1 fi log_success "Node.js version: $(node --version)" # Check for npm if ! check_command npm; then log_error "npm is required but not installed" exit 1 fi # Check for yt-dlp if ! check_command yt-dlp; then log_warning "yt-dlp is not installed or not in PATH" log_warning "Install with: pip install yt-dlp OR brew install yt-dlp" log_warning "The application will not be able to download videos without yt-dlp" else log_success "yt-dlp version: $(yt-dlp --version)" fi echo "" ################################################################################ # Check for existing process ################################################################################ if [ -f "$PID_FILE" ]; then OLD_PID=$(cat "$PID_FILE") if ps -p "$OLD_PID" > /dev/null 2>&1; then log_error "VidRip is already running (PID: $OLD_PID)" log_info "Stop it first with: kill $OLD_PID" exit 1 else log_warning "Stale PID file found, removing..." rm -f "$PID_FILE" fi fi ################################################################################ # Create necessary directories ################################################################################ log_info "Creating necessary directories..." mkdir -p "$LOG_DIR" mkdir -p "$BACKEND_DIR/downloads" mkdir -p "$BACKEND_DIR/dist" log_success "Directories created" echo "" ################################################################################ # Install Dependencies ################################################################################ log_info "Installing dependencies..." # Backend dependencies log_info "Installing backend dependencies..." cd "$BACKEND_DIR" if [ ! -d "node_modules" ]; then npm install --production=false else log_info "Backend node_modules already exists, skipping install" fi log_success "Backend dependencies installed" # Frontend dependencies log_info "Installing frontend dependencies..." cd "$FRONTEND_DIR" if [ ! -d "node_modules" ]; then npm install --production=false else log_info "Frontend node_modules already exists, skipping install" fi log_success "Frontend dependencies installed" cd "$SCRIPT_DIR" echo "" ################################################################################ # Build Applications ################################################################################ log_info "Building applications..." # Build backend log_info "Building backend (TypeScript compilation)..." cd "$BACKEND_DIR" npm run build if [ ! -f "dist/server.js" ]; then log_error "Backend build failed - dist/server.js not found" exit 1 fi log_success "Backend built successfully" # Build frontend log_info "Building frontend (Vite production build)..." cd "$FRONTEND_DIR" npm run build if [ ! -d "dist" ]; then log_error "Frontend build failed - dist directory not found" exit 1 fi log_success "Frontend built successfully" cd "$SCRIPT_DIR" echo "" ################################################################################ # Generate Caddyfile (if needed) ################################################################################ if [ ! -f "$SCRIPT_DIR/Caddyfile" ]; then log_info "Caddyfile not found. Let's create one!" echo "" # Ask for domain read -p "Enter your domain name (or press Enter to skip): " DOMAIN_INPUT if [ -n "$DOMAIN_INPUT" ]; then log_info "Generating Caddyfile for domain: $DOMAIN_INPUT" cat > "$SCRIPT_DIR/Caddyfile" << EOF # VidRip Caddyfile # Auto-generated configuration for ${DOMAIN_INPUT} ${DOMAIN_INPUT} { # Enable compression encode gzip zstd # Security headers header { # Enable HSTS (forces HTTPS) Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" # Prevent clickjacking X-Frame-Options "SAMEORIGIN" # Prevent MIME type sniffing X-Content-Type-Options "nosniff" # Enable XSS protection X-XSS-Protection "1; mode=block" # Referrer policy Referrer-Policy "strict-origin-when-cross-origin" # Remove server header for security -Server } # API routes - proxy to backend handle /api/* { reverse_proxy localhost:3001 { # Health check health_uri /api/health health_interval 10s health_timeout 5s # Headers header_up Host {host} header_up X-Real-IP {remote_host} header_up X-Forwarded-For {remote_host} header_up X-Forwarded-Proto {scheme} } } # Serve frontend static files handle { # Root directory is the frontend build output root * ${WEB_ROOT} # Try files first, fall back to index.html for SPA routing try_files {path} /index.html # Serve files file_server # Cache static assets @static { path *.js *.css *.woff *.woff2 *.ttf *.eot *.ico *.png *.jpg *.jpeg *.gif *.svg *.webp } header @static { Cache-Control "public, max-age=31536000, immutable" } # Don't cache index.html @html { path *.html } header @html { Cache-Control "no-cache, no-store, must-revalidate" } } # Logging log { output file /var/log/caddy/vidrip-access.log { roll_size 100mb roll_keep 10 } format json } } EOF log_success "Caddyfile created successfully!" log_info "You can edit it later at: $SCRIPT_DIR/Caddyfile" else log_info "Skipping Caddyfile generation" log_info "You can create it manually later or use nginx/Apache" fi echo "" else log_info "Caddyfile already exists, skipping generation" echo "" fi ################################################################################ # Deploy Frontend to Web Root ################################################################################ log_info "Deploying frontend to web root..." # Check if we have permissions to write to /var/www if [ -w "/var/www" ]; then # Create web root directory sudo mkdir -p "$WEB_ROOT" # Copy frontend build to web root log_info "Copying frontend build to $WEB_ROOT..." sudo rm -rf "$WEB_ROOT"/* sudo cp -r "$FRONTEND_DIR/dist/"* "$WEB_ROOT/" # Set proper permissions sudo chown -R www-data:www-data "$WEB_ROOT" 2>/dev/null || sudo chown -R $USER:$USER "$WEB_ROOT" sudo chmod -R 755 "$WEB_ROOT" log_success "Frontend deployed to $WEB_ROOT" else log_warning "No write permission to /var/www" log_warning "Run with sudo to deploy frontend, or manually copy:" log_warning " sudo mkdir -p $WEB_ROOT" log_warning " sudo cp -r $FRONTEND_DIR/dist/* $WEB_ROOT/" log_warning " sudo chown -R www-data:www-data $WEB_ROOT" log_warning " sudo chmod -R 755 $WEB_ROOT" fi echo "" ################################################################################ # Start Backend Server ################################################################################ log_info "Starting VidRip backend server..." if [ "$USE_SYSTEMD" = true ]; then # Systemd mode log_info "Using systemd service..." # Check if running as root or with sudo if [ "$EUID" -ne 0 ]; then log_error "Systemd mode requires root privileges" log_error "Please run with: sudo $0 --systemd" exit 1 fi # Check if service file exists SERVICE_FILE="$SCRIPT_DIR/vidrip-backend.service" if [ ! -f "$SERVICE_FILE" ]; then log_error "Service file not found: $SERVICE_FILE" log_error "Please ensure vidrip-backend.service exists in the project directory" exit 1 fi # Update service file with correct paths TEMP_SERVICE="/tmp/vidrip-backend.service" sed -e "s|/opt/vidrip|$SCRIPT_DIR|g" \ -e "s|User=vidrip|User=$SUDO_USER|g" \ -e "s|Group=vidrip|Group=$SUDO_USER|g" \ -e "s|/usr/bin/node|$(which node)|g" \ "$SERVICE_FILE" > "$TEMP_SERVICE" # Install service file cp "$TEMP_SERVICE" /etc/systemd/system/vidrip-backend.service rm "$TEMP_SERVICE" log_info "Service file installed to /etc/systemd/system/vidrip-backend.service" # Reload systemd systemctl daemon-reload # Enable and start service systemctl enable vidrip-backend systemctl restart vidrip-backend # Wait and check status sleep 2 if systemctl is-active --quiet vidrip-backend; then log_success "VidRip backend service started successfully!" echo "" systemctl status vidrip-backend --no-pager -l else log_error "Service failed to start" log_error "Check status with: sudo systemctl status vidrip-backend" log_error "View logs with: sudo journalctl -u vidrip-backend -n 50" exit 1 fi else # Traditional nohup mode log_info "Using nohup mode..." # Check for existing process if [ -f "$PID_FILE" ]; then OLD_PID=$(cat "$PID_FILE") if ps -p "$OLD_PID" > /dev/null 2>&1; then log_error "VidRip is already running (PID: $OLD_PID)" log_info "Stop it first with: ./stop-production.sh" exit 1 else log_warning "Stale PID file found, removing..." rm -f "$PID_FILE" fi fi # Setup environment export NODE_ENV=production # Start the backend server cd "$BACKEND_DIR" # Run in background with output redirected to log files nohup node dist/server.js > "$LOG_FILE" 2> "$ERROR_LOG_FILE" & SERVER_PID=$! # Save PID echo "$SERVER_PID" > "$PID_FILE" # Wait a moment and check if process is still running sleep 2 if ! ps -p "$SERVER_PID" > /dev/null 2>&1; then log_error "Server failed to start" log_error "Check logs at:" log_error " - $LOG_FILE" log_error " - $ERROR_LOG_FILE" rm -f "$PID_FILE" exit 1 fi log_success "VidRip backend started successfully!" echo "" log_info "Process ID: $SERVER_PID" log_info "PID file: $PID_FILE" log_info "Log file: $LOG_FILE" log_info "Error log: $ERROR_LOG_FILE" echo "" # Check for port in logs (default 3001) sleep 1 if grep -q "Server running" "$LOG_FILE" 2>/dev/null; then PORT_INFO=$(grep "Server running" "$LOG_FILE" | tail -1) log_success "$PORT_INFO" else log_info "Server should be running on port 3001 (or PORT from .env)" fi fi echo "" log_info "===================================================================" log_info "VidRip is now running in production mode" log_info "===================================================================" echo "" log_info "Backend Server:" log_info " Running on port 3001 (or PORT from .env)" if [ "$USE_SYSTEMD" = true ]; then log_info " Mode: systemd service" log_info " Service: vidrip-backend" else log_info " Mode: nohup background process" log_info " PID: $SERVER_PID" fi echo "" log_info "Frontend:" log_info " Deployed to: $WEB_ROOT" echo "" if [ "$USE_SYSTEMD" = true ]; then log_info "Service Management:" log_info " Stop: sudo systemctl stop vidrip-backend" log_info " Restart: sudo systemctl restart vidrip-backend" log_info " Status: sudo systemctl status vidrip-backend" log_info " Disable: sudo systemctl disable vidrip-backend" echo "" log_info "View Logs:" log_info " sudo journalctl -u vidrip-backend -f" log_info " tail -f $LOG_FILE" else log_info "To stop the backend service:" log_info " ./stop-production.sh" echo "" log_info "To view logs:" log_info " tail -f $LOG_FILE" echo "" log_info "To view errors:" log_info " tail -f $ERROR_LOG_FILE" fi echo "" if [ -f "$SCRIPT_DIR/Caddyfile" ]; then log_warning "NEXT STEPS - Caddy Setup:" log_warning " 1. Install Caddy: https://caddyserver.com/docs/install" log_warning " Quick install (Ubuntu/Debian):" log_warning " sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https" log_warning " curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg" log_warning " curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list" log_warning " sudo apt update && sudo apt install caddy" echo "" log_warning " 2. Copy Caddyfile to Caddy config directory:" log_warning " sudo cp $SCRIPT_DIR/Caddyfile /etc/caddy/Caddyfile" echo "" log_warning " 3. Start Caddy:" log_warning " sudo systemctl enable caddy" log_warning " sudo systemctl start caddy" echo "" log_warning " 4. Configure firewall to allow ports 80/443:" log_warning " sudo ufw allow 80/tcp" log_warning " sudo ufw allow 443/tcp" echo "" log_success "Caddy will automatically obtain SSL certificates from Let's Encrypt!" else log_warning "NEXT STEPS:" log_warning " 1. Install Caddy: https://caddyserver.com/docs/install" log_warning " 2. Edit Caddyfile and replace 'your-domain.com' with your domain" log_warning " 3. Start Caddy: sudo caddy start" log_warning " (or for testing: caddy run)" log_warning " 4. Configure firewall to allow ports 80/443" fi echo "" log_info "Alternative web servers:" log_info " - See DEPLOYMENT.md for nginx/Apache configurations" echo "" # Register cleanup on script exit trap cleanup_on_exit EXIT exit 0