fix: DockerSecretsResolver - don't normalize absolute paths like /var/www/html/...
Some checks failed
Deploy Application / deploy (push) Has been cancelled
Some checks failed
Deploy Application / deploy (push) Has been cancelled
This commit is contained in:
236
deployment/scripts/rollback.sh
Executable file
236
deployment/scripts/rollback.sh
Executable file
@@ -0,0 +1,236 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# ============================================================================
|
||||
# Rollback Deployment Script
|
||||
# ============================================================================
|
||||
# Restores previous deployment from backup
|
||||
# Based on rollback logic from Gitea workflows
|
||||
# ============================================================================
|
||||
|
||||
# Color output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Usage function
|
||||
usage() {
|
||||
echo "Usage: $0 <environment> [backup_name]"
|
||||
echo ""
|
||||
echo "Arguments:"
|
||||
echo " environment staging or production"
|
||||
echo " backup_name (optional) specific backup to restore"
|
||||
echo " If not specified, restores latest backup"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 staging # Restore latest staging backup"
|
||||
echo " $0 production # Restore latest production backup"
|
||||
echo " $0 production backup_20250124_143022 # Restore specific backup"
|
||||
echo ""
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Validate arguments
|
||||
if [ $# -lt 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
ENVIRONMENT="$1"
|
||||
SPECIFIC_BACKUP="${2:-}"
|
||||
|
||||
# Validate environment
|
||||
if [ "$ENVIRONMENT" != "staging" ] && [ "$ENVIRONMENT" != "production" ]; then
|
||||
echo -e "${RED}❌ Error: Invalid environment '${ENVIRONMENT}'${NC}"
|
||||
echo "Must be 'staging' or 'production'"
|
||||
usage
|
||||
fi
|
||||
|
||||
# Set environment-specific variables
|
||||
if [ "$ENVIRONMENT" = "staging" ]; then
|
||||
REMOTE_USER="${STAGING_USER:-deploy}"
|
||||
REMOTE_HOST="${STAGING_HOST:-staging.michaelschiemer.de}"
|
||||
REMOTE_PORT="${STAGING_SSH_PORT:-22}"
|
||||
REMOTE_PATH="/opt/framework-staging"
|
||||
COMPOSE_FILES="docker-compose.base.yml -f docker-compose.staging.yml"
|
||||
else
|
||||
REMOTE_USER="${PRODUCTION_USER:-deploy}"
|
||||
REMOTE_HOST="${PRODUCTION_HOST:-michaelschiemer.de}"
|
||||
REMOTE_PORT="${PRODUCTION_SSH_PORT:-22}"
|
||||
REMOTE_PATH="/opt/framework-production"
|
||||
COMPOSE_FILES="docker-compose.base.yml -f docker-compose.prod.yml"
|
||||
fi
|
||||
|
||||
# Validation
|
||||
if [ -z "$REMOTE_HOST" ]; then
|
||||
echo -e "${RED}❌ Error: ${ENVIRONMENT^^}_HOST environment variable is required${NC}"
|
||||
echo "Export ${ENVIRONMENT^^}_HOST before running this script"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=================================================="
|
||||
echo "🔄 Starting Rollback: ${ENVIRONMENT}"
|
||||
echo "=================================================="
|
||||
echo "Remote: ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PORT}"
|
||||
echo "Path: ${REMOTE_PATH}"
|
||||
if [ -n "$SPECIFIC_BACKUP" ]; then
|
||||
echo "Target Backup: ${SPECIFIC_BACKUP}"
|
||||
else
|
||||
echo "Target Backup: Latest available"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Confirm rollback
|
||||
echo -e "${YELLOW}⚠️ WARNING: This will rollback the ${ENVIRONMENT} deployment${NC}"
|
||||
echo -e "${YELLOW} Current deployment will be stopped and replaced with backup${NC}"
|
||||
echo ""
|
||||
read -p "Are you sure you want to continue? (yes/no): " CONFIRM
|
||||
|
||||
if [ "$CONFIRM" != "yes" ]; then
|
||||
echo "Rollback cancelled"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Step 1: List available backups
|
||||
echo -e "${GREEN}[1/5] Listing available backups...${NC}"
|
||||
ssh -p "${REMOTE_PORT}" "${REMOTE_USER}@${REMOTE_HOST}" "
|
||||
cd ${REMOTE_PATH}
|
||||
|
||||
echo 'Available backups:'
|
||||
ls -dt backup_* 2>/dev/null || {
|
||||
echo '❌ No backups found'
|
||||
exit 1
|
||||
}
|
||||
"
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}❌ No backups available for rollback${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Step 2: Determine which backup to restore
|
||||
echo -e "${GREEN}[2/5] Determining backup to restore...${NC}"
|
||||
if [ -n "$SPECIFIC_BACKUP" ]; then
|
||||
BACKUP_TO_RESTORE="$SPECIFIC_BACKUP"
|
||||
echo "Using specified backup: ${BACKUP_TO_RESTORE}"
|
||||
else
|
||||
BACKUP_TO_RESTORE=$(ssh -p "${REMOTE_PORT}" "${REMOTE_USER}@${REMOTE_HOST}" "
|
||||
cd ${REMOTE_PATH}
|
||||
ls -dt backup_* 2>/dev/null | head -n1
|
||||
")
|
||||
echo "Using latest backup: ${BACKUP_TO_RESTORE}"
|
||||
fi
|
||||
|
||||
# Verify backup exists
|
||||
ssh -p "${REMOTE_PORT}" "${REMOTE_USER}@${REMOTE_HOST}" "
|
||||
cd ${REMOTE_PATH}
|
||||
if [ ! -d '${BACKUP_TO_RESTORE}' ]; then
|
||||
echo '❌ Backup ${BACKUP_TO_RESTORE} not found'
|
||||
exit 1
|
||||
fi
|
||||
echo '✅ Backup ${BACKUP_TO_RESTORE} verified'
|
||||
"
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}❌ Backup verification failed${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Step 3: Stop current deployment
|
||||
echo -e "${GREEN}[3/5] Stopping current deployment...${NC}"
|
||||
ssh -p "${REMOTE_PORT}" "${REMOTE_USER}@${REMOTE_HOST}" "
|
||||
cd ${REMOTE_PATH}/current
|
||||
|
||||
echo 'Stopping containers...'
|
||||
docker-compose -f ${COMPOSE_FILES} down 2>/dev/null || {
|
||||
echo '⚠️ Some containers may not have stopped cleanly'
|
||||
}
|
||||
|
||||
echo '✅ Current deployment stopped'
|
||||
"
|
||||
|
||||
# Step 4: Restore backup
|
||||
echo -e "${GREEN}[4/5] Restoring backup...${NC}"
|
||||
ssh -p "${REMOTE_PORT}" "${REMOTE_USER}@${REMOTE_HOST}" "
|
||||
cd ${REMOTE_PATH}
|
||||
|
||||
# Backup current (failed) deployment for investigation
|
||||
if [ -d 'current' ]; then
|
||||
failed_backup=\"failed_\$(date +%Y%m%d_%H%M%S)\"
|
||||
echo \"Archiving failed deployment as \${failed_backup}...\"
|
||||
mv current \"\${failed_backup}\"
|
||||
fi
|
||||
|
||||
# Restore backup
|
||||
echo 'Restoring backup ${BACKUP_TO_RESTORE}...'
|
||||
cp -r '${BACKUP_TO_RESTORE}' current
|
||||
|
||||
echo '✅ Backup restored'
|
||||
"
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}❌ Backup restoration failed${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Step 5: Start restored deployment
|
||||
echo -e "${GREEN}[5/5] Starting restored deployment...${NC}"
|
||||
ssh -p "${REMOTE_PORT}" "${REMOTE_USER}@${REMOTE_HOST}" "
|
||||
cd ${REMOTE_PATH}/current
|
||||
|
||||
echo 'Starting containers...'
|
||||
docker-compose -f ${COMPOSE_FILES} up -d
|
||||
|
||||
# Wait for services
|
||||
echo 'Waiting for services to start...'
|
||||
sleep 30
|
||||
|
||||
# Verify deployment
|
||||
echo 'Verifying deployment...'
|
||||
docker-compose -f ${COMPOSE_FILES} ps
|
||||
|
||||
echo '✅ Restored deployment is running'
|
||||
"
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${RED}❌ Failed to start restored deployment${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Health check
|
||||
echo ""
|
||||
echo -e "${GREEN}Performing health check...${NC}"
|
||||
ssh -p "${REMOTE_PORT}" "${REMOTE_USER}@${REMOTE_HOST}" "
|
||||
cd ${REMOTE_PATH}/current
|
||||
|
||||
# Wait a bit more for full initialization
|
||||
sleep 10
|
||||
|
||||
# Check container health
|
||||
healthy_containers=\$(docker-compose -f ${COMPOSE_FILES} ps --filter 'status=running' | wc -l)
|
||||
echo \"Healthy containers: \${healthy_containers}\"
|
||||
|
||||
if [ \"\${healthy_containers}\" -gt 0 ]; then
|
||||
echo '✅ Containers are running'
|
||||
else
|
||||
echo '⚠️ No containers running - manual investigation required'
|
||||
fi
|
||||
"
|
||||
|
||||
echo ""
|
||||
echo "=================================================="
|
||||
echo -e "${GREEN}✅ Rollback Complete${NC}"
|
||||
echo "=================================================="
|
||||
echo "Environment: ${ENVIRONMENT}"
|
||||
echo "Restored: ${BACKUP_TO_RESTORE}"
|
||||
echo "Completed at: $(date)"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " - Verify application: https://${REMOTE_HOST}"
|
||||
echo " - Monitor logs: ssh ${REMOTE_USER}@${REMOTE_HOST} 'cd ${REMOTE_PATH}/current && docker-compose logs -f'"
|
||||
echo " - Check status: ssh ${REMOTE_USER}@${REMOTE_HOST} 'cd ${REMOTE_PATH}/current && docker-compose ps'"
|
||||
echo ""
|
||||
echo "Failed deployment archived as: failed_YYYYMMDD_HHMMSS (if applicable)"
|
||||
echo "You can investigate the failure by SSH'ing to the server and examining:"
|
||||
echo " ${REMOTE_PATH}/failed_*"
|
||||
echo ""
|
||||
Reference in New Issue
Block a user