mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 07:11:08 -05:00
- Implemented a new HTML template for the Road Trip Planner. - Integrated Leaflet.js for interactive mapping and routing. - Added functionality for searching and selecting parks to include in a trip. - Enabled drag-and-drop reordering of selected parks. - Included trip optimization and route calculation features. - Created a summary display for trip statistics. - Added functionality to save trips and manage saved trips. - Enhanced UI with responsive design and dark mode support.
340 lines
8.6 KiB
Bash
Executable File
340 lines
8.6 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# ThrillWiki VM Deployment Script
|
|
# This script runs on the Linux VM to deploy the latest code and restart the server
|
|
|
|
set -e # Exit on any error
|
|
|
|
# Configuration
|
|
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
LOG_DIR="$PROJECT_DIR/logs"
|
|
BACKUP_DIR="$PROJECT_DIR/backups"
|
|
DEPLOY_LOG="$LOG_DIR/deploy.log"
|
|
SERVICE_NAME="thrillwiki"
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Logging function
|
|
log() {
|
|
local message="[$(date +'%Y-%m-%d %H:%M:%S')] $1"
|
|
echo -e "${BLUE}${message}${NC}"
|
|
echo "$message" >> "$DEPLOY_LOG"
|
|
}
|
|
|
|
log_success() {
|
|
local message="[$(date +'%Y-%m-%d %H:%M:%S')] ✓ $1"
|
|
echo -e "${GREEN}${message}${NC}"
|
|
echo "$message" >> "$DEPLOY_LOG"
|
|
}
|
|
|
|
log_warning() {
|
|
local message="[$(date +'%Y-%m-%d %H:%M:%S')] ⚠ $1"
|
|
echo -e "${YELLOW}${message}${NC}"
|
|
echo "$message" >> "$DEPLOY_LOG"
|
|
}
|
|
|
|
log_error() {
|
|
local message="[$(date +'%Y-%m-%d %H:%M:%S')] ✗ $1"
|
|
echo -e "${RED}${message}${NC}"
|
|
echo "$message" >> "$DEPLOY_LOG"
|
|
}
|
|
|
|
# Create necessary directories
|
|
create_directories() {
|
|
log "Creating necessary directories..."
|
|
mkdir -p "$LOG_DIR" "$BACKUP_DIR"
|
|
log_success "Directories created"
|
|
}
|
|
|
|
# Backup current deployment
|
|
backup_current() {
|
|
log "Creating backup of current deployment..."
|
|
local timestamp=$(date +'%Y%m%d_%H%M%S')
|
|
local backup_path="$BACKUP_DIR/backup_$timestamp"
|
|
|
|
# Create backup of current code
|
|
if [ -d "$PROJECT_DIR/.git" ]; then
|
|
local current_commit=$(git -C "$PROJECT_DIR" rev-parse HEAD)
|
|
echo "$current_commit" > "$backup_path.commit"
|
|
log_success "Backup created with commit: ${current_commit:0:8}"
|
|
else
|
|
log_warning "Not a git repository, skipping backup"
|
|
fi
|
|
}
|
|
|
|
# Stop the service
|
|
stop_service() {
|
|
log "Stopping ThrillWiki service..."
|
|
|
|
# Stop systemd service if it exists
|
|
if systemctl is-active --quiet "$SERVICE_NAME" 2>/dev/null; then
|
|
sudo systemctl stop "$SERVICE_NAME"
|
|
log_success "Systemd service stopped"
|
|
else
|
|
log "Systemd service not running"
|
|
fi
|
|
|
|
# Kill any remaining Django processes on port 8000
|
|
if lsof -ti :8000 >/dev/null 2>&1; then
|
|
log "Stopping processes on port 8000..."
|
|
lsof -ti :8000 | xargs kill -9 2>/dev/null || true
|
|
log_success "Port 8000 processes stopped"
|
|
fi
|
|
|
|
# Clean up Python cache
|
|
log "Cleaning Python cache..."
|
|
find "$PROJECT_DIR" -type d -name "__pycache__" -exec rm -r {} + 2>/dev/null || true
|
|
log_success "Python cache cleaned"
|
|
}
|
|
|
|
# Update code from git
|
|
update_code() {
|
|
log "Updating code from git repository..."
|
|
|
|
cd "$PROJECT_DIR"
|
|
|
|
# Fetch latest changes
|
|
git fetch origin
|
|
log "Fetched latest changes"
|
|
|
|
# Get current and new commit info
|
|
local old_commit=$(git rev-parse HEAD)
|
|
local new_commit=$(git rev-parse origin/main)
|
|
|
|
if [ "$old_commit" = "$new_commit" ]; then
|
|
log_warning "No new commits to deploy"
|
|
return 0
|
|
fi
|
|
|
|
log "Updating from ${old_commit:0:8} to ${new_commit:0:8}"
|
|
|
|
# Pull latest changes
|
|
git reset --hard origin/main
|
|
log_success "Code updated successfully"
|
|
|
|
# Show what changed
|
|
log "Changes in this deployment:"
|
|
git log --oneline "$old_commit..$new_commit" || true
|
|
}
|
|
|
|
# Install/update dependencies
|
|
update_dependencies() {
|
|
log "Updating dependencies..."
|
|
|
|
cd "$PROJECT_DIR"
|
|
|
|
# Check if UV is installed
|
|
if ! command -v uv &> /dev/null; then
|
|
log_error "UV is not installed. Installing UV..."
|
|
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
source $HOME/.cargo/env
|
|
fi
|
|
|
|
# Sync dependencies
|
|
uv sync --no-dev || {
|
|
log_error "Failed to sync dependencies"
|
|
return 1
|
|
}
|
|
|
|
log_success "Dependencies updated"
|
|
}
|
|
|
|
# Run database migrations
|
|
run_migrations() {
|
|
log "Running database migrations..."
|
|
|
|
cd "$PROJECT_DIR"
|
|
|
|
# Check for pending migrations
|
|
if uv run manage.py showmigrations --plan | grep -q "\[ \]"; then
|
|
log "Applying database migrations..."
|
|
uv run manage.py migrate || {
|
|
log_error "Database migrations failed"
|
|
return 1
|
|
}
|
|
log_success "Database migrations completed"
|
|
else
|
|
log "No pending migrations"
|
|
fi
|
|
}
|
|
|
|
# Collect static files
|
|
collect_static() {
|
|
log "Collecting static files..."
|
|
|
|
cd "$PROJECT_DIR"
|
|
|
|
uv run manage.py collectstatic --noinput || {
|
|
log_warning "Static file collection failed, continuing..."
|
|
}
|
|
|
|
log_success "Static files collected"
|
|
}
|
|
|
|
# Start the service
|
|
start_service() {
|
|
log "Starting ThrillWiki service..."
|
|
|
|
cd "$PROJECT_DIR"
|
|
|
|
# Start systemd service if it exists
|
|
if systemctl list-unit-files | grep -q "^$SERVICE_NAME.service"; then
|
|
sudo systemctl start "$SERVICE_NAME"
|
|
sudo systemctl enable "$SERVICE_NAME"
|
|
|
|
# Wait for service to start
|
|
sleep 5
|
|
|
|
if systemctl is-active --quiet "$SERVICE_NAME"; then
|
|
log_success "Systemd service started successfully"
|
|
else
|
|
log_error "Systemd service failed to start"
|
|
return 1
|
|
fi
|
|
else
|
|
log_warning "Systemd service not found, starting manually..."
|
|
|
|
# Start server in background
|
|
nohup ./scripts/ci-start.sh > "$LOG_DIR/server.log" 2>&1 &
|
|
local server_pid=$!
|
|
|
|
# Wait for server to start
|
|
sleep 5
|
|
|
|
if kill -0 $server_pid 2>/dev/null; then
|
|
echo $server_pid > "$LOG_DIR/server.pid"
|
|
log_success "Server started manually with PID: $server_pid"
|
|
else
|
|
log_error "Failed to start server manually"
|
|
return 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Health check
|
|
health_check() {
|
|
log "Performing health check..."
|
|
|
|
local max_attempts=30
|
|
local attempt=1
|
|
|
|
while [ $attempt -le $max_attempts ]; do
|
|
if curl -f -s http://localhost:8000/health >/dev/null 2>&1; then
|
|
log_success "Health check passed"
|
|
return 0
|
|
fi
|
|
|
|
log "Health check attempt $attempt/$max_attempts failed, retrying..."
|
|
sleep 2
|
|
((attempt++))
|
|
done
|
|
|
|
log_error "Health check failed after $max_attempts attempts"
|
|
return 1
|
|
}
|
|
|
|
# Cleanup old backups
|
|
cleanup_backups() {
|
|
log "Cleaning up old backups..."
|
|
|
|
# Keep only the last 10 backups
|
|
cd "$BACKUP_DIR"
|
|
ls -t backup_*.commit 2>/dev/null | tail -n +11 | xargs rm -f 2>/dev/null || true
|
|
|
|
log_success "Old backups cleaned up"
|
|
}
|
|
|
|
# Rollback function
|
|
rollback() {
|
|
log_error "Deployment failed, attempting rollback..."
|
|
|
|
local latest_backup=$(ls -t "$BACKUP_DIR"/backup_*.commit 2>/dev/null | head -n 1)
|
|
|
|
if [ -n "$latest_backup" ]; then
|
|
local backup_commit=$(cat "$latest_backup")
|
|
log "Rolling back to commit: ${backup_commit:0:8}"
|
|
|
|
cd "$PROJECT_DIR"
|
|
git reset --hard "$backup_commit"
|
|
|
|
# Restart service
|
|
stop_service
|
|
start_service
|
|
|
|
if health_check; then
|
|
log_success "Rollback completed successfully"
|
|
else
|
|
log_error "Rollback failed - manual intervention required"
|
|
fi
|
|
else
|
|
log_error "No backup found for rollback"
|
|
fi
|
|
}
|
|
|
|
# Main deployment function
|
|
deploy() {
|
|
log "=== ThrillWiki Deployment Started ==="
|
|
log "Timestamp: $(date)"
|
|
log "User: $(whoami)"
|
|
log "Host: $(hostname)"
|
|
|
|
# Trap errors for rollback
|
|
trap rollback ERR
|
|
|
|
create_directories
|
|
backup_current
|
|
stop_service
|
|
update_code
|
|
update_dependencies
|
|
run_migrations
|
|
collect_static
|
|
start_service
|
|
health_check
|
|
cleanup_backups
|
|
|
|
# Remove error trap
|
|
trap - ERR
|
|
|
|
log_success "=== Deployment Completed Successfully ==="
|
|
log "Server is now running the latest code"
|
|
log "Check logs at: $LOG_DIR/"
|
|
}
|
|
|
|
# Script execution
|
|
case "${1:-deploy}" in
|
|
deploy)
|
|
deploy
|
|
;;
|
|
stop)
|
|
stop_service
|
|
;;
|
|
start)
|
|
start_service
|
|
;;
|
|
restart)
|
|
stop_service
|
|
start_service
|
|
health_check
|
|
;;
|
|
status)
|
|
if systemctl is-active --quiet "$SERVICE_NAME" 2>/dev/null; then
|
|
echo "Service is running"
|
|
elif [ -f "$LOG_DIR/server.pid" ] && kill -0 "$(cat "$LOG_DIR/server.pid")" 2>/dev/null; then
|
|
echo "Server is running manually"
|
|
else
|
|
echo "Service is not running"
|
|
fi
|
|
;;
|
|
health)
|
|
health_check
|
|
;;
|
|
*)
|
|
echo "Usage: $0 {deploy|stop|start|restart|status|health}"
|
|
exit 1
|
|
;;
|
|
esac |