#!/bin/bash set -e echo "🚀 Starting optimized deployment with full rollback support..." # Backup database (per Deployment, inkl. Metadaten für Rollback) echo "💾 Creating database backup for this deployment..." # Try to find database path from docker-compose.yml or .env DB_PATH="" # Check if docker-compose.yml exists and extract DATABASE_URL if [ -f "docker-compose.yml" ]; then DB_PATH=$(grep -oP 'DATABASE_URL=file:\K[^\s]+' docker-compose.yml | head -1) fi # Fallback to .env if not found if [ -z "$DB_PATH" ] && [ -f ".env" ]; then DB_PATH=$(grep -oP '^DATABASE_URL=file:\K.+' .env | head -1) fi # Remove any quotes and resolve path DB_PATH=$(echo "$DB_PATH" | tr -d '"' | tr -d "'") if [ -n "$DB_PATH" ]; then # Convert container path to host path if needed # /app/data/prod.db -> ./data/prod.db DB_PATH=$(echo "$DB_PATH" | sed 's|/app/|./|') if [ -f "$DB_PATH" ]; then # Create backups directory mkdir -p ./backups # Create timestamped backup DEPLOY_TS="$(date +%Y%m%d_%H%M%S)" BACKUP_FILE="./backups/$(basename "$DB_PATH" .db)_${DEPLOY_TS}.db" cp "$DB_PATH" "$BACKUP_FILE" echo "✅ Database backed up to: $BACKUP_FILE" # Store metadata for restore (Timestamp, DB-Path, Git-Commit) CURRENT_COMMIT="$(git rev-parse HEAD || echo 'unknown')" { echo "timestamp=${DEPLOY_TS}" echo "db_path=${DB_PATH}" echo "backup_file=${BACKUP_FILE}" echo "git_commit=${CURRENT_COMMIT}" } > "./backups/last_deploy.meta" # Append to history manifest (eine Zeile pro Deployment) echo "${DEPLOY_TS}|${DB_PATH}|${BACKUP_FILE}|${CURRENT_COMMIT}" >> "./backups/deploy_history.log" # Keep only last 10 backups ls -t ./backups/*.db | tail -n +11 | xargs -r rm echo "🧹 Cleaned old backups (keeping last 10)" else echo "⚠️ Database file not found at: $DB_PATH" fi else echo "⚠️ Could not determine database path from config files" fi # Nur neueste Version holen (shallow fetch), vollständiges Repo ist im Deployment nicht nötig echo "📥 Fetching latest commit (shallow clone) from git..." git fetch --prune --tags --depth=1 origin master git reset --hard origin/master # Prüfe und erstelle/repariere Netzwerk falls nötig echo "🌐 Prüfe Docker-Netzwerk..." if ! docker network ls | grep -q "hoerdle_default"; then echo " Netzwerk existiert nicht, erstelle es..." docker network create hoerdle_default echo "✅ Netzwerk erstellt" else # Prüfe ob Netzwerk falsche Labels hat (wird durch external: true umgangen) echo "✅ Netzwerk existiert bereits" echo " (Hinweis: Falls Warnungen über falsche Labels erscheinen, verwende: ./scripts/fix-network.sh)" fi echo "" # Build new image in background (doesn't stop running container) echo "🔨 Building new Docker image (this runs while app is still online)..." docker compose build # Quick restart with pre-built image echo "🔄 Restarting with new image (minimal downtime)..." docker compose up -d # Clean up old images echo "🧹 Cleaning up old images..." docker image prune -f echo "✅ Deployment complete!" echo "" echo "📊 Showing logs (Ctrl+C to exit)..." docker compose logs -f