- Introduced `install_dependencies_if_needed` function to conditionally install dependencies based on the presence and changes in `package-lock.json`. - Updated the deployment process to log build output to a file for better error tracking. - Modified Nuxt configuration to disable source maps in production and prevent reporting of compressed sizes in Vite builds.
588 lines
20 KiB
Bash
Executable File
588 lines
20 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
# Immer im Repo-Verzeichnis arbeiten (wichtig für Backup/Restore mit relativen Pfaden)
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
cd "$SCRIPT_DIR"
|
|
|
|
# Deployment Script für Harheimer TC Website
|
|
# Sichert Produktivdaten vor dem Build und stellt sie danach wieder her
|
|
|
|
echo "=== Harheimer TC Deployment ==="
|
|
echo ""
|
|
echo "Working directory: $(pwd)"
|
|
echo ""
|
|
|
|
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
echo "ERROR: Dieses Script muss im Git-Repository ausgeführt werden (kein .git gefunden)."
|
|
exit 1
|
|
fi
|
|
|
|
# Optional (empfohlen): Persistente Daten außerhalb des Git-Repos halten und per Symlink einbinden.
|
|
# Das verhindert zuverlässig, dass Git jemals Produktivdaten überschreibt.
|
|
DEPLOY_HOME="${DEPLOY_HOME:-${HOME:-/tmp}}"
|
|
DATA_ROOT="${DATA_ROOT:-$DEPLOY_HOME/harheimertc-data}"
|
|
BACKUP_ROOT="${BACKUP_ROOT:-$DEPLOY_HOME/harheimertc-backups}"
|
|
|
|
mkdir -p "$DATA_ROOT" "$BACKUP_ROOT"
|
|
|
|
ensure_symlink_dir() {
|
|
local src="$1" # z.B. server/data
|
|
local target="$2" # z.B. /var/lib/harheimertc/server-data
|
|
|
|
mkdir -p "$(dirname "$src")"
|
|
mkdir -p "$target"
|
|
|
|
if [ -L "$src" ]; then
|
|
return 0
|
|
fi
|
|
|
|
if [ -d "$src" ]; then
|
|
echo " Moving $src -> $target (first-time migration)"
|
|
# Merge existing content into target
|
|
cp -a "$src/." "$target/" || true
|
|
rm -rf "$src"
|
|
fi
|
|
|
|
ln -s "$target" "$src"
|
|
echo " Linked $src -> $target"
|
|
}
|
|
|
|
has_tracked_files_under() {
|
|
local prefix="$1" # e.g. public/data
|
|
# If any file is tracked under this path, symlinking the directory will break git operations
|
|
git ls-files "$prefix" | head -n 1 | grep -q .
|
|
}
|
|
|
|
install_dependencies() {
|
|
if [ -f "package-lock.json" ]; then
|
|
echo " Running: npm ci"
|
|
npm ci
|
|
else
|
|
echo " WARNING: package-lock.json fehlt. Führe npm install aus..."
|
|
npm install
|
|
fi
|
|
}
|
|
|
|
install_dependencies_if_needed() {
|
|
local cache_dir=".deploy-cache"
|
|
local lock_hash_file="$cache_dir/package-lock.sha256"
|
|
local current_lock_hash=""
|
|
local previous_lock_hash=""
|
|
|
|
if [ ! -f "package-lock.json" ]; then
|
|
echo " package-lock.json fehlt, führe npm install aus..."
|
|
install_dependencies
|
|
return 0
|
|
fi
|
|
|
|
mkdir -p "$cache_dir"
|
|
current_lock_hash="$(sha256sum package-lock.json | awk '{print $1}')"
|
|
if [ -f "$lock_hash_file" ]; then
|
|
previous_lock_hash="$(cat "$lock_hash_file" 2>/dev/null || true)"
|
|
fi
|
|
|
|
if [ ! -d "node_modules" ]; then
|
|
echo " node_modules fehlt, installiere Dependencies..."
|
|
install_dependencies
|
|
elif [ "$current_lock_hash" != "$previous_lock_hash" ]; then
|
|
echo " package-lock.json geändert, führe npm ci aus..."
|
|
install_dependencies
|
|
else
|
|
echo " package-lock.json unverändert, überspringe npm ci"
|
|
fi
|
|
|
|
printf '%s\n' "$current_lock_hash" > "$lock_hash_file"
|
|
}
|
|
|
|
use_project_node() {
|
|
export NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
|
|
if [ -s "$NVM_DIR/nvm.sh" ]; then
|
|
# shellcheck disable=SC1090
|
|
. "$NVM_DIR/nvm.sh"
|
|
if [ -f ".nvmrc" ]; then
|
|
echo " Using Node version from .nvmrc..."
|
|
nvm use
|
|
fi
|
|
fi
|
|
}
|
|
|
|
ensure_node_version() {
|
|
if ! command -v node >/dev/null 2>&1; then
|
|
echo "ERROR: Node.js ist nicht im PATH."
|
|
exit 1
|
|
fi
|
|
|
|
local node_version
|
|
node_version="$(node -p 'process.versions.node')"
|
|
if ! node -e 'const [major, minor] = process.versions.node.split(".").map(Number); process.exit(major > 22 || (major === 22 && minor >= 12) ? 0 : 1)' >/dev/null 2>&1; then
|
|
echo "ERROR: Node.js >= 22.12.0 wird benötigt, aktuell ist $node_version aktiv."
|
|
echo "Bitte Node 22 installieren/aktivieren, z.B.:"
|
|
echo " nvm install 22"
|
|
echo " nvm alias default 22"
|
|
exit 1
|
|
fi
|
|
|
|
echo " Node.js $node_version"
|
|
}
|
|
|
|
sync_public_documents_to_build() {
|
|
if [ ! -d "public/documents" ]; then
|
|
echo " No public/documents directory to sync"
|
|
return 0
|
|
fi
|
|
|
|
if [ ! -d ".output/public" ]; then
|
|
echo "ERROR: .output/public fehlt, kann public/documents nicht synchronisieren."
|
|
exit 1
|
|
fi
|
|
|
|
mkdir -p ".output/public/documents"
|
|
cp -a "public/documents/." ".output/public/documents/"
|
|
echo " ✓ public/documents -> .output/public/documents synchronisiert"
|
|
|
|
local template_pdf="beitrittserklärung_template.pdf"
|
|
if [ -f "public/documents/$template_pdf" ]; then
|
|
local source_size output_size
|
|
source_size=$(stat -f%z "public/documents/$template_pdf" 2>/dev/null || stat -c%s "public/documents/$template_pdf" 2>/dev/null || echo "0")
|
|
output_size=$(stat -f%z ".output/public/documents/$template_pdf" 2>/dev/null || stat -c%s ".output/public/documents/$template_pdf" 2>/dev/null || echo "0")
|
|
|
|
if [ "$source_size" != "$output_size" ] || [ "$source_size" = "0" ]; then
|
|
echo "ERROR: .output/public/documents/$template_pdf stimmt nicht mit public/documents überein (Source: $source_size, Output: $output_size)."
|
|
exit 1
|
|
fi
|
|
|
|
echo " ✓ $template_pdf im Build verifiziert ($output_size bytes)"
|
|
fi
|
|
}
|
|
|
|
echo "0. Ensuring persistent data directories (recommended)..."
|
|
# IMPORTANT: Only symlink server/data if it's not tracked by git.
|
|
if has_tracked_files_under "server/data"; then
|
|
echo " Skipping symlink for server/data (tracked files detected in git)."
|
|
echo " Recommendation: remove server/data/** from git history and keep them only as production data."
|
|
else
|
|
ensure_symlink_dir "server/data" "$DATA_ROOT/server-data"
|
|
fi
|
|
|
|
# IMPORTANT: Only symlink public/data if it's not tracked by git.
|
|
# Otherwise git will error with "path is beyond a symbolic link".
|
|
if has_tracked_files_under "public/data"; then
|
|
echo " Skipping symlink for public/data (tracked files detected in git)."
|
|
echo " Recommendation: remove public/data/*.csv from git history and keep them only as production data."
|
|
else
|
|
ensure_symlink_dir "public/data" "$DATA_ROOT/public-data"
|
|
fi
|
|
|
|
ensure_symlink_dir "public/uploads" "$DATA_ROOT/public-uploads"
|
|
echo ""
|
|
|
|
# 1. BACKUP: Laufende Produktivdaten VOR allen Git-Operationen sichern
|
|
echo "1. Backing up current production data (pre-git)..."
|
|
|
|
# Human readable timestamp (lokal)
|
|
BACKUP_TS="$(date +"%Y-%m-%d_%H-%M-%S")"
|
|
BACKUP_DIR="$BACKUP_ROOT/backup_$BACKUP_TS"
|
|
mkdir -p "$BACKUP_DIR"
|
|
echo " Backup directory: $BACKUP_DIR"
|
|
|
|
# Backup server data (JSON) und CSVs immer vom Dateisystem, nicht aus 'stash'
|
|
if [ -d server/data ]; then
|
|
cp -a server/data "$BACKUP_DIR/server-data"
|
|
echo " Backed up server/data -> $BACKUP_DIR/server-data"
|
|
else
|
|
echo "ERROR: server/data existiert nicht. Abbruch, damit wir keine Repo-Defaults ausrollen."
|
|
exit 1
|
|
fi
|
|
|
|
if ls public/data/*.csv >/dev/null 2>&1; then
|
|
mkdir -p "$BACKUP_DIR/public-data"
|
|
cp -a public/data/*.csv "$BACKUP_DIR/public-data/"
|
|
echo " Backed up public/data/*.csv -> $BACKUP_DIR/public-data/"
|
|
else
|
|
echo " No public CSVs to backup (public/data/*.csv not found)"
|
|
fi
|
|
# Prefer internal public-data under server/data/public-data for backups; fallback to legacy public/data
|
|
if ls server/data/public-data/*.csv >/dev/null 2>&1; then
|
|
mkdir -p "$BACKUP_DIR/public-data"
|
|
cp -a server/data/public-data/*.csv "$BACKUP_DIR/public-data/"
|
|
echo " Backed up server/data/public-data/*.csv -> $BACKUP_DIR/public-data/"
|
|
elif ls public/data/*.csv >/dev/null 2>&1; then
|
|
mkdir -p "$BACKUP_DIR/public-data"
|
|
cp -a public/data/*.csv "$BACKUP_DIR/public-data/"
|
|
echo " Backed up public/data/*.csv -> $BACKUP_DIR/public-data/"
|
|
else
|
|
echo " No public CSVs to backup (server/data/public-data or public/data not found)"
|
|
fi
|
|
|
|
# 2. Handle local changes and Git Pull
|
|
echo "2. Handling local changes and pulling latest from git..."
|
|
|
|
# Check if there are merge conflicts first
|
|
if [ -n "$(git status --porcelain | grep '^UU\|^AA\|^DD')" ]; then
|
|
echo " Resolving existing merge conflicts..."
|
|
git reset --hard HEAD
|
|
fi
|
|
|
|
# Ensure git operations can run even if we have untracked local artifacts (e.g. backups/)
|
|
# We avoid `git stash` (breaks with symlinked tracked paths). Instead, hard-reset and clean safely.
|
|
echo " Resetting working tree to HEAD (production data will be restored from backup)..."
|
|
git reset --hard HEAD
|
|
|
|
echo " Cleaning untracked files (excluding data dirs/backups/.env)..."
|
|
git clean -fd \
|
|
-e server/data \
|
|
-e public/data \
|
|
-e public/uploads \
|
|
-e backups \
|
|
-e .env || true
|
|
|
|
# Pull latest changes
|
|
echo " Pulling latest changes..."
|
|
git fetch origin main
|
|
git checkout -B main origin/main
|
|
if ! git reset --hard origin/main; then
|
|
echo "ERROR: git pull fehlgeschlagen."
|
|
echo ""
|
|
echo "Häufige Ursache: SSH-Key für den aktuellen User fehlt."
|
|
echo "Prüfen:"
|
|
echo " ssh -T git@tsschulz.de"
|
|
echo ""
|
|
echo "Optional auf HTTPS wechseln:"
|
|
echo " git remote set-url origin https://tsschulz.de/<owner>/<repo>.git"
|
|
echo "Oder SSH-Key für User $(id -un) hinterlegen."
|
|
exit 1
|
|
fi
|
|
|
|
# Reset any accidental changes from stash restore (should be none now)
|
|
git reset --hard HEAD >/dev/null 2>&1
|
|
|
|
# WICHTIG: Entferne public/data Dateien aus Git-Index, falls sie getrackt sind
|
|
# (Sie sollten in .gitignore sein, aber falls sie historisch getrackt wurden)
|
|
if git ls-files --error-unmatch public/data/*.csv >/dev/null 2>&1; then
|
|
echo " WARNING: public/data/*.csv Dateien sind im Git getrackt!"
|
|
echo " Entferne sie aus dem Git-Index (Dateien bleiben erhalten)..."
|
|
git rm --cached public/data/*.csv 2>/dev/null || true
|
|
fi
|
|
|
|
# 3. Install dependencies
|
|
echo ""
|
|
echo "3. Installing dependencies..."
|
|
use_project_node
|
|
ensure_node_version
|
|
install_dependencies_if_needed
|
|
|
|
# 4. Remove old build (but keep data!)
|
|
echo ""
|
|
echo "4. Cleaning build artifacts..."
|
|
# Sicherstellen, dass .output vollständig gelöscht wird
|
|
if [ -d ".output" ]; then
|
|
echo " Removing .output directory..."
|
|
rm -rf .output
|
|
# Prüfen, ob wirklich gelöscht wurde
|
|
if [ -d ".output" ]; then
|
|
echo "WARNING: .output konnte nicht vollständig gelöscht werden. Versuche erneut..."
|
|
sleep 2
|
|
rm -rf .output
|
|
if [ -d ".output" ]; then
|
|
echo "ERROR: .output konnte auch nach erneutem Versuch nicht gelöscht werden!"
|
|
echo "Bitte manuell prüfen und löschen: rm -rf .output"
|
|
exit 1
|
|
fi
|
|
fi
|
|
echo " ✓ .output gelöscht"
|
|
fi
|
|
|
|
# .nuxt standardmäßig behalten (beschleunigt Folge-Builds deutlich).
|
|
# Für erzwungenen Clean-Build: CLEAN_NUXT_CACHE=1 ./deploy-production.sh
|
|
if [ "${CLEAN_NUXT_CACHE:-0}" = "1" ]; then
|
|
if [ -d ".nuxt" ]; then
|
|
echo " CLEAN_NUXT_CACHE=1 gesetzt: entferne .nuxt cache..."
|
|
rm -rf .nuxt
|
|
echo " ✓ .nuxt gelöscht"
|
|
fi
|
|
else
|
|
echo " Behalte .nuxt cache für schnelleren Build (CLEAN_NUXT_CACHE=1 für Clean-Build)"
|
|
fi
|
|
|
|
# Prüfe, ob node_modules vorhanden ist (für npm run build)
|
|
if [ ! -d "node_modules" ]; then
|
|
echo ""
|
|
echo "WARNING: node_modules fehlt. Installiere Dependencies..."
|
|
install_dependencies
|
|
fi
|
|
|
|
# 5. Build
|
|
echo ""
|
|
echo "5. Building application..."
|
|
echo " Running: npm run build"
|
|
echo " (This may take a few minutes...)"
|
|
|
|
# Clean-Build: Stelle sicher, dass node_modules aktuell ist
|
|
echo " Checking dependencies..."
|
|
if [ ! -f "node_modules/.package-lock.json" ] && [ ! -f "package-lock.json" ]; then
|
|
echo " WARNING: package-lock.json fehlt. Führe npm install aus..."
|
|
install_dependencies
|
|
fi
|
|
|
|
# Build mit expliziter Fehlerbehandlung und gleichzeitiger Log-Datei
|
|
BUILD_LOG_FILE=".deploy-cache/build-$(date +%Y%m%d-%H%M%S).log"
|
|
mkdir -p ".deploy-cache"
|
|
if npm run build 2>&1 | tee "$BUILD_LOG_FILE"; then
|
|
BUILD_EXIT_CODE=0
|
|
else
|
|
BUILD_EXIT_CODE=$?
|
|
fi
|
|
|
|
if [ "$BUILD_EXIT_CODE" -ne 0 ]; then
|
|
echo ""
|
|
echo "ERROR: Build fehlgeschlagen mit Exit-Code $BUILD_EXIT_CODE"
|
|
echo "Bitte prüfen Sie die Build-Ausgabe oben auf Fehler."
|
|
echo "Build-Log: $BUILD_LOG_FILE"
|
|
exit 1
|
|
fi
|
|
|
|
echo ""
|
|
echo " Synchronizing public documents into build output..."
|
|
sync_public_documents_to_build
|
|
|
|
# Prüfe auf Warnungen im Build-Output, die auf Probleme hinweisen
|
|
if rg -i "error|failed|missing" "$BUILD_LOG_FILE" >/dev/null 2>&1; then
|
|
echo ""
|
|
echo "WARNING: Build-Output enthält möglicherweise Fehler oder Warnungen."
|
|
echo "Bitte prüfen Sie die Ausgabe oben."
|
|
echo "Build-Log: $BUILD_LOG_FILE"
|
|
fi
|
|
|
|
# Prüfe, ob der Build erfolgreich war - mehrere Checks
|
|
echo ""
|
|
echo " Verifying build output..."
|
|
|
|
BUILD_FAILED=0
|
|
|
|
# Check 1: _nuxt Verzeichnis
|
|
if [ ! -d ".output/public/_nuxt" ]; then
|
|
echo "ERROR: .output/public/_nuxt Verzeichnis fehlt!"
|
|
BUILD_FAILED=1
|
|
else
|
|
NUXT_FILES=$(find .output/public/_nuxt -type f 2>/dev/null | wc -l)
|
|
echo " ✓ .output/public/_nuxt vorhanden ($NUXT_FILES Dateien)"
|
|
if [ "$NUXT_FILES" -eq 0 ]; then
|
|
echo "ERROR: .output/public/_nuxt ist leer!"
|
|
BUILD_FAILED=1
|
|
else
|
|
# Prüfe, ob wichtige Dateien vorhanden sind
|
|
JS_FILES=$(find .output/public/_nuxt -name "*.js" 2>/dev/null | wc -l)
|
|
CSS_FILES=$(find .output/public/_nuxt -name "*.css" 2>/dev/null | wc -l)
|
|
echo " ✓ JS-Dateien: $JS_FILES, CSS-Dateien: $CSS_FILES"
|
|
if [ "$JS_FILES" -eq 0 ]; then
|
|
echo "ERROR: Keine JS-Dateien in .output/public/_nuxt gefunden!"
|
|
BUILD_FAILED=1
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Check 1b: _nuxt/builds Verzeichnis (für Meta-Dateien)
|
|
if [ -d ".output/public/_nuxt/builds" ]; then
|
|
BUILD_META_FILES=$(find .output/public/_nuxt/builds -type f 2>/dev/null | wc -l)
|
|
echo " ✓ .output/public/_nuxt/builds vorhanden ($BUILD_META_FILES Meta-Dateien)"
|
|
else
|
|
echo "WARNING: .output/public/_nuxt/builds fehlt (kann in manchen Nuxt-Versionen normal sein)"
|
|
fi
|
|
|
|
# Check 2: Server index.mjs
|
|
if [ ! -f ".output/server/index.mjs" ]; then
|
|
echo "ERROR: .output/server/index.mjs fehlt!"
|
|
BUILD_FAILED=1
|
|
else
|
|
echo " ✓ .output/server/index.mjs vorhanden"
|
|
fi
|
|
|
|
# Check 3: Public Verzeichnis
|
|
if [ ! -d ".output/public" ]; then
|
|
echo "ERROR: .output/public Verzeichnis fehlt!"
|
|
BUILD_FAILED=1
|
|
else
|
|
echo " ✓ .output/public vorhanden"
|
|
fi
|
|
|
|
# Check 4: Server Verzeichnis
|
|
if [ ! -d ".output/server" ]; then
|
|
echo "ERROR: .output/server Verzeichnis fehlt!"
|
|
BUILD_FAILED=1
|
|
else
|
|
echo " ✓ .output/server vorhanden"
|
|
fi
|
|
|
|
if [ "$BUILD_FAILED" -eq 1 ]; then
|
|
echo ""
|
|
echo "ERROR: Build-Verifikation fehlgeschlagen!"
|
|
echo "Bitte führen Sie manuell aus:"
|
|
echo " rm -rf .output .nuxt"
|
|
echo " npm run build"
|
|
exit 1
|
|
fi
|
|
|
|
echo " ✓ Build erfolgreich verifiziert"
|
|
|
|
# 6. Restore Production Data (überschreibe Repo-Defaults mit Backup)
|
|
echo ""
|
|
echo "6. Restoring production data..."
|
|
|
|
# Stelle server/data vollständig wieder her (inkl. config.json, users.json, news.json, sessions.json, members.json, membership-applications)
|
|
if [ ! -d "$BACKUP_DIR/server-data" ]; then
|
|
echo "ERROR: Backup-Verzeichnis $BACKUP_DIR/server-data fehlt. Abbruch."
|
|
exit 1
|
|
fi
|
|
|
|
# WICHTIG: Prüfe, ob server/data ein Symlink ist (z.B. auf Backup-Verzeichnis)
|
|
# Falls ja, entferne den Symlink, damit wir in das echte Verzeichnis kopieren können
|
|
if [ -L "server/data" ]; then
|
|
echo " WARNING: server/data ist ein Symlink. Entferne Symlink..."
|
|
rm "server/data"
|
|
fi
|
|
|
|
# Stelle sicher, dass server/data ein echtes Verzeichnis ist
|
|
if [ ! -d "server/data" ]; then
|
|
mkdir -p server/data
|
|
fi
|
|
|
|
# Kopiere Daten vom Backup (verwende -L, um Symlinks zu folgen, falls nötig)
|
|
cp -aL "$BACKUP_DIR/server-data/." server/data/
|
|
echo " Restored server/data from backup ($BACKUP_DIR/server-data)."
|
|
|
|
# Stelle alle CSVs wieder her
|
|
if ls "$BACKUP_DIR/public-data"/*.csv >/dev/null 2>&1; then
|
|
mkdir -p public/data
|
|
|
|
# WICHTIG: Überschreibe auch Dateien, die aus dem Git-Repository kommen
|
|
# Verwende cp mit -f (force) um sicherzustellen, dass Backup-Dateien Vorrang haben
|
|
for csv_file in "$BACKUP_DIR/public-data"/*.csv; do
|
|
filename=$(basename "$csv_file")
|
|
# Überschreibe explizit, auch wenn Datei bereits existiert
|
|
cp -f "$csv_file" "public/data/$filename"
|
|
# Stelle sicher, dass die Datei wirklich überschrieben wurde
|
|
if [ -f "public/data/$filename" ]; then
|
|
# Prüfe, ob die Datei wirklich vom Backup kommt (Größenvergleich)
|
|
backup_size=$(stat -f%z "$csv_file" 2>/dev/null || stat -c%s "$csv_file" 2>/dev/null || echo "0")
|
|
restored_size=$(stat -f%z "public/data/$filename" 2>/dev/null || stat -c%s "public/data/$filename" 2>/dev/null || echo "0")
|
|
if [ "$backup_size" = "$restored_size" ] && [ "$backup_size" != "0" ]; then
|
|
echo " ✓ Restored public/data/$filename from backup ($backup_size bytes)"
|
|
else
|
|
echo " ⚠ WARNING: public/data/$filename Größe stimmt nicht überein (Backup: $backup_size, Restored: $restored_size)"
|
|
fi
|
|
else
|
|
echo " ❌ ERROR: Konnte public/data/$filename nicht wiederherstellen!"
|
|
fi
|
|
done
|
|
|
|
echo " ✓ All public/data/*.csv files restored from backup ($BACKUP_DIR/public-data)."
|
|
|
|
# Zusätzliche Sicherheit: Entferne public/data Dateien aus Git-Index, falls sie getrackt sind
|
|
# (nach dem Restore, damit sie nicht beim nächsten git reset überschrieben werden)
|
|
if git ls-files --error-unmatch public/data/*.csv >/dev/null 2>&1; then
|
|
echo " WARNING: public/data/*.csv Dateien sind noch im Git getrackt!"
|
|
echo " Entferne sie aus dem Git-Index (Dateien bleiben erhalten)..."
|
|
git rm --cached public/data/*.csv 2>/dev/null || true
|
|
echo " ✓ public/data/*.csv aus Git-Index entfernt"
|
|
fi
|
|
else
|
|
echo " No public CSVs to restore"
|
|
fi
|
|
|
|
# Sanity Check: users.json muss existieren und darf nicht leer sein
|
|
if [ ! -s server/data/users.json ]; then
|
|
echo "ERROR: server/data/users.json fehlt oder ist leer nach Restore. Abbruch."
|
|
exit 1
|
|
fi
|
|
|
|
# 7. Cleanup (Backups werden bewusst behalten)
|
|
echo ""
|
|
echo "7. Keeping backups in $BACKUP_ROOT (no git stash used)."
|
|
|
|
# 8. Restart PM2
|
|
echo ""
|
|
echo "8. Restarting PM2..."
|
|
|
|
# Prüfe, ob PM2 installiert ist
|
|
if ! command -v pm2 &> /dev/null; then
|
|
echo "ERROR: PM2 ist nicht installiert oder nicht im PATH!"
|
|
echo "Bitte installieren Sie PM2: npm install -g pm2"
|
|
exit 1
|
|
fi
|
|
|
|
# Funktion zum Starten/Neustarten einer PM2-Instanz
|
|
restart_pm2_instance() {
|
|
local instance_name=$1
|
|
if ! pm2 describe "$instance_name" &> /dev/null; then
|
|
echo " WARNING: PM2-Prozess '$instance_name' existiert nicht."
|
|
echo " Versuche, den Prozess zu starten..."
|
|
if pm2 start harheimertc.config.cjs --only "$instance_name" --update-env; then
|
|
echo " ✓ PM2-Prozess '$instance_name' gestartet"
|
|
return 0
|
|
else
|
|
echo " ERROR: Konnte PM2-Prozess '$instance_name' nicht starten."
|
|
return 1
|
|
fi
|
|
else
|
|
echo " Restarting $instance_name with --update-env..."
|
|
if pm2 restart "$instance_name" --update-env; then
|
|
echo " ✓ PM2-Prozess '$instance_name' neu gestartet"
|
|
return 0
|
|
else
|
|
echo " ERROR: PM2-Restart für '$instance_name' fehlgeschlagen!"
|
|
return 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Starte/Neustarte beide Instanzen
|
|
INSTANCE_ERRORS=0
|
|
|
|
if ! restart_pm2_instance "harheimertc"; then
|
|
INSTANCE_ERRORS=$((INSTANCE_ERRORS + 1))
|
|
fi
|
|
|
|
if ! restart_pm2_instance "harheimertc-3102"; then
|
|
INSTANCE_ERRORS=$((INSTANCE_ERRORS + 1))
|
|
fi
|
|
|
|
# Prüfe, ob beide Prozesse laufen
|
|
sleep 2
|
|
echo ""
|
|
echo " Checking PM2 instances status..."
|
|
|
|
if pm2 describe harheimertc | grep -q "online"; then
|
|
echo " ✓ PM2-Prozess 'harheimertc' läuft (online)"
|
|
else
|
|
echo " WARNING: PM2-Prozess 'harheimertc' ist nicht online. Prüfe Logs: pm2 logs harheimertc"
|
|
INSTANCE_ERRORS=$((INSTANCE_ERRORS + 1))
|
|
fi
|
|
|
|
if pm2 describe harheimertc-3102 | grep -q "online"; then
|
|
echo " ✓ PM2-Prozess 'harheimertc-3102' läuft (online)"
|
|
else
|
|
echo " WARNING: PM2-Prozess 'harheimertc-3102' ist nicht online. Prüfe Logs: pm2 logs harheimertc-3102"
|
|
INSTANCE_ERRORS=$((INSTANCE_ERRORS + 1))
|
|
fi
|
|
|
|
if [ "$INSTANCE_ERRORS" -gt 0 ]; then
|
|
echo ""
|
|
echo "WARNING: Einige PM2-Instanzen haben Probleme. Bitte manuell prüfen:"
|
|
echo " pm2 status"
|
|
echo " pm2 logs harheimertc"
|
|
echo " pm2 logs harheimertc-3102"
|
|
fi
|
|
|
|
echo ""
|
|
echo "=== Deployment completed successfully! ==="
|
|
echo "The application is now running with the latest code and your production data preserved."
|
|
echo ""
|
|
echo "Useful commands:"
|
|
echo " pm2 logs harheimertc # View logs (Port 3100)"
|
|
echo " pm2 logs harheimertc-3102 # View logs (Port 3102)"
|
|
echo " pm2 status # View status"
|
|
echo " pm2 restart harheimertc # Restart instance on port 3100"
|
|
echo " pm2 restart harheimertc-3102 # Restart instance on port 3102"
|
|
echo " pm2 restart all # Restart all instances"
|