#!/bin/bash # AutonetSellCar Server2 Setup Script # Run this script on server2 (192.168.0.202) to set up the deployment infrastructure # # Usage: # scp setup-server2.sh user@192.168.0.202:/tmp/ # ssh user@192.168.0.202 'chmod +x /tmp/setup-server2.sh && /tmp/setup-server2.sh' set -e echo "========================================" echo " AutonetSellCar Server2 Setup" echo "========================================" echo "" # Check if running as appropriate user if [ "$(id -u)" = "0" ]; then echo "WARNING: Running as root. Will change ownership to: $SUDO_USER" DEPLOY_USER="${SUDO_USER:-root}" else DEPLOY_USER="$(whoami)" fi echo "Deploy user: $DEPLOY_USER" echo "" # 1. Create directory structure echo "[1/6] Creating directory structure..." sudo mkdir -p /opt/autonet/{git,staging,production,releases,scripts,logs} sudo chown -R "$DEPLOY_USER:$DEPLOY_USER" /opt/autonet echo " Created /opt/autonet/{git,staging,production,releases,scripts,logs}" # 2. Initialize bare git repository echo "" echo "[2/6] Initializing bare Git repository..." cd /opt/autonet/git if [ ! -d "autonet.git" ]; then git init --bare autonet.git echo " Created /opt/autonet/git/autonet.git" else echo " Repository already exists, skipping..." fi # 3. Copy deployment scripts echo "" echo "[3/6] Setting up deployment scripts..." # Create deploy-staging.sh cat > /opt/autonet/scripts/deploy-staging.sh << 'STAGING_SCRIPT' #!/bin/bash set -e STAGING_DIR="/opt/autonet/staging" LOG_FILE="/opt/autonet/logs/staging-deploy.log" log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } mkdir -p /opt/autonet/logs log "==========================================" log "Starting Staging Deployment" log "==========================================" cd $STAGING_DIR log "[1/4] Stopping existing containers..." docker compose -f docker-compose.staging.yml down 2>/dev/null || true log "[2/4] Building containers..." docker compose -f docker-compose.staging.yml build --no-cache log "[3/4] Starting containers..." docker compose -f docker-compose.staging.yml up -d log "[4/4] Waiting for services..." sleep 15 # Health check BACKEND_OK=false FRONTEND_OK=false for i in {1..5}; do if curl -sf http://localhost:8001/docs > /dev/null 2>&1; then BACKEND_OK=true break fi sleep 5 done for i in {1..5}; do if curl -sf http://localhost:3001 > /dev/null 2>&1; then FRONTEND_OK=true break fi sleep 5 done if $BACKEND_OK && $FRONTEND_OK; then log "Staging Deployment SUCCESSFUL!" log "Frontend: http://192.168.0.202:3001" log "Backend: http://192.168.0.202:8001/docs" else log "Staging Deployment FAILED!" exit 1 fi STAGING_SCRIPT chmod +x /opt/autonet/scripts/deploy-staging.sh echo " Created deploy-staging.sh" # Create main deploy.sh (simplified version for setup) cat > /opt/autonet/scripts/deploy.sh << 'DEPLOY_SCRIPT' #!/bin/bash set -e STAGING_DIR="/opt/autonet/staging" PROD_DIR="/opt/autonet/production" RELEASES_DIR="/opt/autonet/releases" TIMESTAMP=$(date +%Y%m%d_%H%M%S) case "$1" in promote) echo "Promoting Staging -> Production..." # Backup current if [ -d "$PROD_DIR/frontend" ]; then mkdir -p "$RELEASES_DIR/$TIMESTAMP" rsync -a --exclude='*.db' --exclude='uploads/' "$PROD_DIR/" "$RELEASES_DIR/$TIMESTAMP/" echo "$TIMESTAMP" > "$PROD_DIR/.previous_release" fi # Stop production cd "$PROD_DIR" 2>/dev/null && docker compose -f docker-compose.production.yml down 2>/dev/null || true # Copy staging to production mkdir -p "$PROD_DIR"/{frontend,backend,agent} rsync -av --delete --exclude='*.db' --exclude='uploads/' "$STAGING_DIR/frontend/" "$PROD_DIR/frontend/" rsync -av --delete --exclude='*.db' --exclude='uploads/' "$STAGING_DIR/backend/" "$PROD_DIR/backend/" rsync -av --delete "$STAGING_DIR/agent/" "$PROD_DIR/agent/" 2>/dev/null || true cp "$STAGING_DIR/docker-compose.production.yml" "$PROD_DIR/" # Build and start cd "$PROD_DIR" docker compose -f docker-compose.production.yml build docker compose -f docker-compose.production.yml up -d echo "$TIMESTAMP" > "$PROD_DIR/.current_release" echo "Production deployed! Release: $TIMESTAMP" ;; rollback) PREV=$(cat "$PROD_DIR/.previous_release" 2>/dev/null || cat "$PROD_DIR/.current_release" 2>/dev/null) [ -d "$RELEASES_DIR/$PREV" ] || { echo "No release to rollback"; exit 1; } cd "$PROD_DIR" && docker compose -f docker-compose.production.yml down 2>/dev/null || true rsync -av --delete --exclude='*.db' --exclude='uploads/' "$RELEASES_DIR/$PREV/frontend/" "$PROD_DIR/frontend/" rsync -av --delete --exclude='*.db' --exclude='uploads/' "$RELEASES_DIR/$PREV/backend/" "$PROD_DIR/backend/" docker compose -f docker-compose.production.yml build docker compose -f docker-compose.production.yml up -d echo "Rolled back to: $PREV" ;; rollback-to) [ -d "$RELEASES_DIR/$2" ] || { echo "Release not found"; ls "$RELEASES_DIR"; exit 1; } cd "$PROD_DIR" && docker compose -f docker-compose.production.yml down 2>/dev/null || true rsync -av --delete --exclude='*.db' --exclude='uploads/' "$RELEASES_DIR/$2/frontend/" "$PROD_DIR/frontend/" rsync -av --delete --exclude='*.db' --exclude='uploads/' "$RELEASES_DIR/$2/backend/" "$PROD_DIR/backend/" docker compose -f docker-compose.production.yml build docker compose -f docker-compose.production.yml up -d echo "$2" > "$PROD_DIR/.current_release" echo "Rolled back to: $2" ;; status) echo "=== Staging ===" && docker compose -f "$STAGING_DIR/docker-compose.staging.yml" ps 2>/dev/null || echo "Not running" echo "=== Production ===" && docker compose -f "$PROD_DIR/docker-compose.production.yml" ps 2>/dev/null || echo "Not running" echo "=== Releases ===" && ls -1 "$RELEASES_DIR" 2>/dev/null | tail -5 || echo "None" ;; cleanup) cd "$RELEASES_DIR" && ls -1 | head -n -10 | xargs -r rm -rf echo "Cleaned up old releases" ;; *) echo "Usage: deploy.sh {promote|rollback|rollback-to |status|cleanup}" ;; esac DEPLOY_SCRIPT chmod +x /opt/autonet/scripts/deploy.sh echo " Created deploy.sh" # 4. Setup post-receive hook echo "" echo "[4/6] Setting up Git post-receive hook..." cat > /opt/autonet/git/autonet.git/hooks/post-receive << 'HOOK_SCRIPT' #!/bin/bash STAGING_DIR="/opt/autonet/staging" GIT_DIR="/opt/autonet/git/autonet.git" SCRIPTS_DIR="/opt/autonet/scripts" echo "" echo "========================================" echo " AutonetSellCar - Deploying to Staging" echo "========================================" while read oldrev newrev refname; do branch=$(echo $refname | sed 's/refs\/heads\///') if [ "$branch" = "main" ] || [ "$branch" = "master" ]; then git --work-tree="$STAGING_DIR" --git-dir="$GIT_DIR" checkout -f "$branch" "$SCRIPTS_DIR/deploy-staging.sh" echo "" echo "Staging ready at:" echo " Frontend: http://192.168.0.202:3001" echo " Backend: http://192.168.0.202:8001/docs" echo "" echo "To deploy to production:" echo " /opt/autonet/scripts/deploy.sh promote" fi done HOOK_SCRIPT chmod +x /opt/autonet/git/autonet.git/hooks/post-receive echo " Created post-receive hook" # 5. Check dependencies echo "" echo "[5/6] Checking dependencies..." if command -v docker &> /dev/null; then echo " Docker: $(docker --version)" else echo " WARNING: Docker not found! Please install Docker." fi if command -v docker compose &> /dev/null; then echo " Docker Compose: $(docker compose version)" else echo " WARNING: Docker Compose not found! Please install Docker Compose." fi if command -v git &> /dev/null; then echo " Git: $(git --version)" else echo " WARNING: Git not found! Please install Git." fi if command -v curl &> /dev/null; then echo " curl: installed" else echo " WARNING: curl not found! Please install curl." fi if command -v rsync &> /dev/null; then echo " rsync: installed" else echo " WARNING: rsync not found! Installing..." sudo apt-get update && sudo apt-get install -y rsync fi # 6. Print summary echo "" echo "[6/6] Setup complete!" echo "" echo "========================================" echo " Setup Summary" echo "========================================" echo "" echo "Directory structure:" echo " /opt/autonet/" echo " ├── git/autonet.git/ <- Push code here" echo " ├── staging/ <- Staging environment" echo " ├── production/ <- Production environment" echo " ├── releases/ <- Rollback archives" echo " ├── scripts/ <- Deployment scripts" echo " └── logs/ <- Deployment logs" echo "" echo "Next steps on development server (server4):" echo "" echo " 1. Add remote:" echo " git remote add staging ssh://$DEPLOY_USER@192.168.0.202/opt/autonet/git/autonet.git" echo "" echo " 2. Push code to staging:" echo " git push staging main" echo "" echo " 3. Test at http://192.168.0.202:3001" echo "" echo " 4. Promote to production:" echo " ssh $DEPLOY_USER@192.168.0.202 '/opt/autonet/scripts/deploy.sh promote'" echo "" echo "========================================"