- deploy.sh übergibt jetzt explizit APP_VERSION als Build-Argument - AudioPlayer setzt startTime korrekt beim ersten manuellen Play - Verbesserte Position-Logik in togglePlay() mit Timeout-Bestätigung - Behebt Problem, dass Specials beim ersten Segment statt bei startTime starteten
136 lines
4.6 KiB
Bash
Executable File
136 lines
4.6 KiB
Bash
Executable File
#!/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
|
|
|
|
# Restic backup to remote repository
|
|
./scripts/backup-restic.sh
|
|
|
|
# Nur neueste Version holen (shallow fetch), vollständiges Repo ist im Deployment nicht nötig
|
|
# Wichtig: Tags müssen vollständig geholt werden für Version-Anzeige
|
|
echo "📥 Fetching latest commit and all tags from git..."
|
|
git fetch --prune --tags origin master
|
|
git fetch --tags origin
|
|
git reset --hard origin/master
|
|
|
|
# Determine version: try git tag first, then package.json
|
|
echo "🏷️ Determining version..."
|
|
APP_VERSION=""
|
|
# Try to get exact tag if we're on a tagged commit
|
|
if git describe --tags --exact-match HEAD 2>/dev/null; then
|
|
APP_VERSION=$(git describe --tags --exact-match HEAD 2>/dev/null)
|
|
echo " Found exact tag: $APP_VERSION"
|
|
else
|
|
# Try to get latest tag
|
|
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
|
|
if [ -n "$LATEST_TAG" ]; then
|
|
APP_VERSION="$LATEST_TAG"
|
|
echo " Using latest tag: $APP_VERSION"
|
|
else
|
|
# Fallback to package.json
|
|
if [ -f "package.json" ]; then
|
|
PACKAGE_VERSION=$(grep -o '"version": "[^"]*"' package.json 2>/dev/null | cut -d'"' -f4)
|
|
if [ -n "$PACKAGE_VERSION" ]; then
|
|
APP_VERSION="v${PACKAGE_VERSION}"
|
|
echo " Using package.json version: $APP_VERSION"
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
if [ -z "$APP_VERSION" ]; then
|
|
echo "⚠️ Could not determine version, using 'dev'"
|
|
APP_VERSION="dev"
|
|
fi
|
|
|
|
echo "📦 Building with version: $APP_VERSION"
|
|
|
|
# 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 --build-arg APP_VERSION="$APP_VERSION"
|
|
|
|
# Quick restart with pre-built image
|
|
echo "🔄 Restarting with new image (minimal downtime)..."
|
|
docker compose up -d
|
|
|
|
# Clean up old images and build cache
|
|
echo "🧹 Cleaning up old images..."
|
|
docker image prune -f
|
|
|
|
echo "🧹 Cleaning up build cache..."
|
|
docker builder prune -f
|
|
|
|
echo "✅ Deployment complete!"
|
|
echo ""
|
|
echo "📊 Showing logs (Ctrl+C to exit)..."
|
|
docker compose logs -f
|