voice2text/deploy.sh

406 lines
12 KiB
Bash
Executable file
Raw 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
#############################################
# Voice to Text - Production Deploy Script
#############################################
# Deploys backend (Python API) and frontend (PHP) to production
# Usage: sudo ./deploy.sh [options]
set -e # Exit on error
# 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
# Configuration
BACKEND_DIR="/opt/voice2text"
FRONTEND_DIR="/var/www/html/voice2txt"
SERVICE_NAME="voice2text-api"
SERVICE_FILE="voice2text-api.service"
SERVICE_PATH="/etc/systemd/system/${SERVICE_FILE}"
# Parse command line arguments
DRY_RUN=false
BACKEND_ONLY=false
FRONTEND_ONLY=false
VERBOSE=false
SKIP_GIT_CHECK=false
while [[ $# -gt 0 ]]; do
case $1 in
--dry-run)
DRY_RUN=true
shift
;;
--backend-only)
BACKEND_ONLY=true
shift
;;
--frontend-only)
FRONTEND_ONLY=true
shift
;;
--verbose|-v)
VERBOSE=true
shift
;;
--skip-git-check)
SKIP_GIT_CHECK=true
shift
;;
--help|-h)
echo "Usage: sudo ./deploy.sh [options]"
echo ""
echo "Options:"
echo " --dry-run Show what would be deployed without executing"
echo " --backend-only Deploy only the Python API backend"
echo " --frontend-only Deploy only the PHP frontend"
echo " --verbose, -v Show detailed output"
echo " --skip-git-check Skip the git status verification prompt"
echo " --help, -h Show this help message"
echo ""
echo "Note: This script does NOT pull code from git."
echo " Pull the desired code/branch BEFORE running this script."
exit 0
;;
*)
echo -e "${RED}Unknown option: $1${NC}"
exit 1
;;
esac
done
# Helper functions
print_header() {
echo -e "\n${BLUE}═══════════════════════════════════════════════════${NC}"
echo -e "${BLUE} $1${NC}"
echo -e "${BLUE}═══════════════════════════════════════════════════${NC}\n"
}
print_success() {
echo -e "${GREEN}${NC} $1"
}
print_error() {
echo -e "${RED}${NC} $1"
}
print_warning() {
echo -e "${YELLOW}${NC} $1"
}
print_info() {
echo -e "${BLUE}${NC} $1"
}
run_command() {
if [ "$VERBOSE" = true ]; then
echo -e "${BLUE}Running:${NC} $*"
fi
if [ "$DRY_RUN" = true ]; then
echo -e "${YELLOW}[DRY RUN]${NC} Would execute: $*"
else
"$@"
fi
}
# Pre-flight checks
print_header "Pre-flight Checks"
# Check if running as root
if [ "$EUID" -ne 0 ]; then
print_error "This script must be run as root (use sudo)"
exit 1
fi
print_success "Running as root"
# Check if backend directory exists
if [ ! -d "$BACKEND_DIR" ]; then
print_error "Backend directory not found: $BACKEND_DIR"
print_info "Clone the repo first: git clone <repo-url> $BACKEND_DIR"
exit 1
fi
print_success "Backend directory exists: $BACKEND_DIR"
# Check if we're in a git repo
cd "$BACKEND_DIR"
if [ ! -d .git ]; then
print_error "Not a git repository: $BACKEND_DIR"
exit 1
fi
print_success "Git repository verified"
# Detect if this is first deployment
FIRST_DEPLOY=false
if [ ! -f "$SERVICE_PATH" ]; then
FIRST_DEPLOY=true
print_info "First deployment detected"
else
print_info "Updating existing deployment"
fi
# Verify git status
print_header "Verifying Code Status"
# Show current branch and commit
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
CURRENT_COMMIT=$(git rev-parse --short HEAD)
COMMIT_MESSAGE=$(git log -1 --pretty=%B | head -n 1)
print_info "Current branch: ${GREEN}${CURRENT_BRANCH}${NC}"
print_info "Current commit: ${GREEN}${CURRENT_COMMIT}${NC}"
print_info "Commit message: ${CURRENT_COMMIT} - ${COMMIT_MESSAGE}"
# Check if there are uncommitted changes
if [ -n "$(git status --porcelain)" ]; then
print_warning "There are uncommitted changes in the working directory:"
git status --short
echo ""
fi
# Check if local is behind remote
git fetch origin --quiet
LOCAL=$(git rev-parse @)
REMOTE=$(git rev-parse @{u} 2>/dev/null || echo "")
if [ -n "$REMOTE" ] && [ "$LOCAL" != "$REMOTE" ]; then
print_warning "Your local branch is not up to date with remote!"
print_info "Remote has newer commits. Consider: git pull origin ${CURRENT_BRANCH}"
fi
# Prompt user to confirm they've pulled the latest code
if [ "$SKIP_GIT_CHECK" != true ] && [ "$DRY_RUN" != true ]; then
echo ""
echo -e "${YELLOW}IMPORTANT:${NC} This script does NOT pull code from git."
echo -e " You should pull the desired code BEFORE running this script."
echo ""
read -p "Have you pulled the latest code you want to deploy? (y/n) " -n 1 -r
echo ""
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
print_error "Deployment cancelled. Pull your code first, then run this script again."
exit 1
fi
print_success "Git status verified - proceeding with deployment"
else
if [ "$SKIP_GIT_CHECK" = true ]; then
print_info "Skipping git verification (--skip-git-check)"
fi
print_success "Proceeding with deployment of current code"
fi
# Deploy Backend
if [ "$FRONTEND_ONLY" != true ]; then
print_header "Deploying Backend (Python API)"
cd "$BACKEND_DIR"
# Check for Python
if ! command -v python3 &> /dev/null; then
print_error "Python 3 is not installed"
exit 1
fi
print_success "Python 3 found: $(python3 --version)"
# Create virtual environment if it doesn't exist
if [ ! -d "venv" ]; then
print_info "Creating Python virtual environment..."
run_command python3 -m venv venv
print_success "Virtual environment created"
else
print_success "Virtual environment exists"
fi
# Activate venv and install/update dependencies
print_info "Installing Python dependencies..."
run_command venv/bin/pip install --upgrade pip
run_command venv/bin/pip install -r requirements.txt
print_success "Python dependencies installed"
# Install/update Composer dependencies
if command -v composer &> /dev/null; then
print_info "Installing PHP dependencies (Composer)..."
run_command composer install --no-dev --optimize-autoloader
print_success "Composer dependencies installed"
else
print_warning "Composer not found - skipping PHP dependencies"
fi
# Create outputs directory if it doesn't exist
if [ ! -d "outputs" ]; then
print_info "Creating outputs directory..."
run_command mkdir -p outputs
fi
# Set proper ownership and permissions
print_info "Setting permissions..."
run_command chown -R www-data:www-data "$BACKEND_DIR"
run_command chmod -R 755 "$BACKEND_DIR"
run_command chmod 777 "$BACKEND_DIR/outputs"
print_success "Permissions set"
# Handle .env file
if [ ! -f ".env" ]; then
print_warning ".env file not found in $BACKEND_DIR"
if [ -f ".env.example" ]; then
print_info "Copying .env.example to .env..."
run_command cp .env.example .env
print_warning "IMPORTANT: Edit $BACKEND_DIR/.env with production credentials!"
else
print_error ".env.example not found - cannot create .env"
exit 1
fi
else
print_success ".env file exists (not overwriting)"
fi
# Install systemd service
print_info "Installing systemd service..."
run_command cp "$BACKEND_DIR/$SERVICE_FILE" "$SERVICE_PATH"
run_command systemctl daemon-reload
print_success "Systemd service installed"
# Enable and start/restart service
if [ "$FIRST_DEPLOY" = true ]; then
print_info "Enabling service..."
run_command systemctl enable "$SERVICE_NAME"
print_success "Service enabled"
print_info "Starting service..."
run_command systemctl start "$SERVICE_NAME"
print_success "Service started"
else
print_info "Restarting service..."
run_command systemctl restart "$SERVICE_NAME"
print_success "Service restarted"
fi
# Wait for service to start
print_info "Waiting for service to start..."
sleep 3
# Check service status
if systemctl is-active --quiet "$SERVICE_NAME"; then
print_success "Service is running"
else
print_error "Service failed to start"
echo ""
echo "Service status:"
systemctl status "$SERVICE_NAME" --no-pager
echo ""
echo "Recent logs:"
journalctl -u "$SERVICE_NAME" -n 20 --no-pager
exit 1
fi
# Test API health endpoint
print_info "Testing API health endpoint..."
if curl -sf http://localhost:5010/health > /dev/null; then
print_success "API is responding at http://localhost:5010"
else
print_warning "API health check failed - service may still be starting"
fi
fi
# Deploy Frontend
if [ "$BACKEND_ONLY" != true ]; then
print_header "Deploying Frontend (PHP)"
# Create frontend directory if it doesn't exist
if [ ! -d "$FRONTEND_DIR" ]; then
print_info "Creating frontend directory..."
run_command mkdir -p "$FRONTEND_DIR"
fi
# Copy frontend files
print_info "Copying frontend files..."
# PHP files
run_command cp "$BACKEND_DIR"/*.php "$FRONTEND_DIR/"
# Config files
run_command cp "$BACKEND_DIR/.htaccess" "$FRONTEND_DIR/"
run_command cp "$BACKEND_DIR/.user.ini" "$FRONTEND_DIR/"
# Assets
run_command cp "$BACKEND_DIR/style.css" "$FRONTEND_DIR/"
if [ -f "$BACKEND_DIR/V2T.svg" ]; then
run_command cp "$BACKEND_DIR/V2T.svg" "$FRONTEND_DIR/"
fi
# Composer vendor directory
if [ -d "$BACKEND_DIR/vendor" ]; then
print_info "Copying Composer dependencies..."
run_command cp -r "$BACKEND_DIR/vendor" "$FRONTEND_DIR/"
fi
print_success "Frontend files copied"
# Handle .env file for frontend
if [ ! -f "$FRONTEND_DIR/.env" ]; then
print_warning ".env file not found in $FRONTEND_DIR"
if [ -f "$BACKEND_DIR/.env.example" ]; then
print_info "Copying .env.example to frontend..."
run_command cp "$BACKEND_DIR/.env.example" "$FRONTEND_DIR/.env"
print_warning "IMPORTANT: Edit $FRONTEND_DIR/.env with production credentials!"
fi
else
print_success ".env file exists in frontend (not overwriting)"
fi
# Create outputs directory symlink or copy
if [ ! -d "$FRONTEND_DIR/outputs" ]; then
print_info "Linking outputs directory..."
run_command ln -s "$BACKEND_DIR/outputs" "$FRONTEND_DIR/outputs"
print_success "Outputs directory linked"
fi
# Set proper ownership and permissions
print_info "Setting frontend permissions..."
run_command chown -R www-data:www-data "$FRONTEND_DIR"
run_command chmod -R 755 "$FRONTEND_DIR"
print_success "Frontend permissions set"
fi
# Final summary
print_header "Deployment Summary"
if [ "$BACKEND_ONLY" != true ]; then
echo -e "${GREEN}Frontend:${NC}"
echo " Location: $FRONTEND_DIR"
echo " Files: *.php, style.css, .htaccess, vendor/"
fi
if [ "$FRONTEND_ONLY" != true ]; then
echo -e "${GREEN}Backend:${NC}"
echo " Location: $BACKEND_DIR"
echo " Service: $SERVICE_NAME"
echo " Status: $(systemctl is-active $SERVICE_NAME)"
echo " API: http://localhost:5010"
fi
echo ""
print_success "Deployment completed successfully!"
echo ""
# Show useful commands
print_header "Useful Commands"
echo "Service management:"
echo " systemctl status $SERVICE_NAME # Check service status"
echo " systemctl restart $SERVICE_NAME # Restart service"
echo " systemctl stop $SERVICE_NAME # Stop service"
echo ""
echo "View logs:"
echo " journalctl -u $SERVICE_NAME -f # Follow live logs"
echo " journalctl -u $SERVICE_NAME -n 50 # Last 50 log entries"
echo ""
echo "Test API:"
echo " curl http://localhost:5010/health # Health check"
echo ""
if [ -f "$FRONTEND_DIR/.env" ] && grep -q "DEV_MODE=true" "$FRONTEND_DIR/.env" 2>/dev/null; then
print_warning "WARNING: DEV_MODE=true detected in .env!"
print_warning "Remember to set DEV_MODE=false for production"
fi