All checks were successful
Dev Deployment (Zero Downtime) / deploy-dev (push) Successful in 13m33s
Build Optimizations: - Enable Docker BuildKit cache for faster builds (7min → 3-4min) - Add .dockerignore to reduce build context - Optimize Dockerfile with better layer caching - Run linting and tests in parallel - Skip blocking checks for dev deployments Rollback Functionality: - Add rollback.sh script to restore previous versions - Supports both production and dev environments - Automatic health checks after rollback Security Improvements: - Add authentication to n8n/generate-image endpoint - Add rate limiting to all n8n endpoints (10-30 req/min) - Create email obfuscation utilities - Add ObfuscatedEmail React component - Document security best practices Files: - .dockerignore - Faster builds - scripts/rollback.sh - Rollback functionality - lib/email-obfuscate.ts - Email obfuscation utilities - components/ObfuscatedEmail.tsx - React component - SECURITY_IMPROVEMENTS.md - Security documentation
122 lines
3.1 KiB
Bash
Executable File
122 lines
3.1 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Rollback Script for Portfolio Deployment
|
|
# Restores previous version of the application
|
|
|
|
set -e
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
log() {
|
|
echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
|
|
}
|
|
|
|
error() {
|
|
echo -e "${RED}[ERROR]${NC} $1" >&2
|
|
}
|
|
|
|
success() {
|
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
|
}
|
|
|
|
warning() {
|
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
}
|
|
|
|
# Check if environment is specified
|
|
ENV=${1:-production}
|
|
COMPOSE_FILE="docker-compose.production.yml"
|
|
CONTAINER_NAME="portfolio-app"
|
|
IMAGE_TAG="production"
|
|
|
|
if [ "$ENV" == "dev" ] || [ "$ENV" == "staging" ]; then
|
|
COMPOSE_FILE="docker-compose.staging.yml"
|
|
CONTAINER_NAME="portfolio-app-staging"
|
|
IMAGE_TAG="staging"
|
|
HEALTH_PORT="3002"
|
|
else
|
|
HEALTH_PORT="3000"
|
|
fi
|
|
|
|
log "🔄 Starting rollback for $ENV environment..."
|
|
|
|
# Check if Docker is running
|
|
if ! docker info > /dev/null 2>&1; then
|
|
error "Docker is not running. Please start Docker and try again."
|
|
exit 1
|
|
fi
|
|
|
|
# List available image tags
|
|
log "📋 Available image versions:"
|
|
docker images portfolio-app --format "table {{.Tag}}\t{{.ID}}\t{{.CreatedAt}}" | head -10
|
|
|
|
# Get current container image
|
|
CURRENT_IMAGE=$(docker inspect $CONTAINER_NAME --format='{{.Config.Image}}' 2>/dev/null || echo "")
|
|
if [ ! -z "$CURRENT_IMAGE" ]; then
|
|
log "Current image: $CURRENT_IMAGE"
|
|
fi
|
|
|
|
# Find previous image tags
|
|
PREVIOUS_TAGS=$(docker images portfolio-app --format "{{.Tag}}" | grep -E "^(production|staging|latest|previous|backup)" | grep -v "^$IMAGE_TAG$" | head -5)
|
|
|
|
if [ -z "$PREVIOUS_TAGS" ]; then
|
|
error "No previous images found for rollback!"
|
|
log "Available images:"
|
|
docker images portfolio-app
|
|
exit 1
|
|
fi
|
|
|
|
# Use the first previous tag (most recent)
|
|
PREVIOUS_TAG=$(echo "$PREVIOUS_TAGS" | head -1)
|
|
log "Selected previous image: portfolio-app:$PREVIOUS_TAG"
|
|
|
|
# Confirm rollback
|
|
read -p "Do you want to rollback to portfolio-app:$PREVIOUS_TAG? (y/N): " -n 1 -r
|
|
echo
|
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
log "Rollback cancelled."
|
|
exit 0
|
|
fi
|
|
|
|
# Tag the previous image as current
|
|
log "🔄 Tagging previous image as current..."
|
|
docker tag "portfolio-app:$PREVIOUS_TAG" "portfolio-app:$IMAGE_TAG" || {
|
|
error "Failed to tag previous image"
|
|
exit 1
|
|
}
|
|
|
|
# Stop current container
|
|
log "🛑 Stopping current container..."
|
|
docker compose -f $COMPOSE_FILE down || true
|
|
|
|
# Start with previous image
|
|
log "🚀 Starting previous version..."
|
|
docker compose -f $COMPOSE_FILE up -d
|
|
|
|
# Wait for health check
|
|
log "⏳ Waiting for health check..."
|
|
for i in {1..40}; do
|
|
if curl -f http://localhost:$HEALTH_PORT/api/health > /dev/null 2>&1; then
|
|
success "✅ Rollback successful! Application is healthy."
|
|
break
|
|
fi
|
|
echo -n "."
|
|
sleep 3
|
|
done
|
|
|
|
if ! curl -f http://localhost:$HEALTH_PORT/api/health > /dev/null 2>&1; then
|
|
error "❌ Health check failed after rollback!"
|
|
log "Container logs:"
|
|
docker compose -f $COMPOSE_FILE logs --tail=50
|
|
exit 1
|
|
fi
|
|
|
|
success "🎉 Rollback completed successfully!"
|
|
log "Application is available at: http://localhost:$HEALTH_PORT"
|
|
log "To rollback further, run: ./scripts/rollback.sh $ENV"
|