Files
stechuhr3/deploy.sh

820 lines
25 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# =============================================================================
# TimeClock v3 - Deployment Script für Ubuntu 22.04
# =============================================================================
# Dieses Script automatisiert das Deployment auf dem Produktionsserver
#
# Verwendung:
# ./deploy.sh [OPTION]
#
# Optionen:
# install - Erste Installation (inkl. System-Setup)
# update - Update einer bestehenden Installation
# rollback - Rollback zur vorherigen Version
# backup - Erstelle Backup der Datenbank
# status - Zeige Status der Services
# logs - Zeige Logs
# help - Zeige diese Hilfe
#
# =============================================================================
set -e # Bei Fehler abbrechen
# Farben für Output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Konfiguration
PROJECT_NAME="TimeClock"
PROJECT_DIR="/var/www/timeclock"
BACKEND_DIR="$PROJECT_DIR/backend"
FRONTEND_DIR="$PROJECT_DIR/frontend"
DOMAIN="stechuhr3.tsschulz.de"
BACKUP_DIR="/var/backups/timeclock"
LOG_DIR="/var/log/timeclock"
# Service-Name (PM2 oder systemd)
USE_PM2=true # true für PM2, false für systemd
SERVICE_NAME="timeclock-backend"
# Webserver (nginx oder apache2)
WEBSERVER="apache2" # "nginx" oder "apache2"
# =============================================================================
# Hilfsfunktionen
# =============================================================================
print_info() {
echo -e "${BLUE} $1${NC}"
}
print_success() {
echo -e "${GREEN}$1${NC}"
}
print_warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
print_error() {
echo -e "${RED}$1${NC}"
}
print_header() {
echo ""
echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"
echo -e "${BLUE} $1${NC}"
echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"
echo ""
}
check_root() {
if [ "$EUID" -eq 0 ]; then
print_error "Bitte führe dieses Script NICHT als root aus!"
print_info "Verwende stattdessen sudo für einzelne Befehle."
exit 1
fi
}
check_command() {
if ! command -v $1 &> /dev/null; then
print_error "$1 ist nicht installiert!"
return 1
fi
return 0
}
# =============================================================================
# Installation - Erste Einrichtung
# =============================================================================
install_dependencies() {
print_header "Installiere System-Abhängigkeiten"
print_info "Aktualisiere Paketquellen..."
sudo apt update
print_info "Installiere Node.js 20.x..."
if ! check_command node; then
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
else
print_success "Node.js ist bereits installiert ($(node -v))"
fi
if [ "$WEBSERVER" = "nginx" ]; then
print_info "Installiere Nginx..."
if ! check_command nginx; then
sudo apt install -y nginx
else
print_success "Nginx ist bereits installiert"
fi
else
print_info "Installiere Apache2..."
if ! check_command apache2; then
sudo apt install -y apache2
else
print_success "Apache2 ist bereits installiert"
fi
print_info "Aktiviere Apache2-Module..."
sudo a2enmod proxy proxy_http ssl rewrite headers deflate expires
fi
print_info "Installiere Certbot..."
if ! check_command certbot; then
if [ "$WEBSERVER" = "nginx" ]; then
sudo apt install -y certbot python3-certbot-nginx
else
sudo apt install -y certbot python3-certbot-apache
fi
else
print_success "Certbot ist bereits installiert"
fi
if [ "$USE_PM2" = true ]; then
print_info "Installiere PM2..."
if ! check_command pm2; then
sudo npm install -g pm2
else
print_success "PM2 ist bereits installiert"
fi
fi
print_success "Alle Abhängigkeiten installiert!"
}
setup_directories() {
print_header "Erstelle Verzeichnisse"
print_info "Erstelle Projekt-Verzeichnis..."
sudo mkdir -p $PROJECT_DIR
sudo chown -R $USER:$USER $PROJECT_DIR
print_info "Erstelle Log-Verzeichnis..."
sudo mkdir -p $LOG_DIR
sudo chown -R www-data:www-data $LOG_DIR
print_info "Erstelle Backup-Verzeichnis..."
sudo mkdir -p $BACKUP_DIR
sudo chown -R $USER:$USER $BACKUP_DIR
print_success "Verzeichnisse erstellt!"
}
copy_project_files() {
print_header "Kopiere Projekt-Dateien"
CURRENT_DIR=$(pwd)
print_info "Quell-Verzeichnis: $CURRENT_DIR"
print_info "Ziel-Verzeichnis: $PROJECT_DIR"
# Erstelle Ziel-Verzeichnisse falls nicht vorhanden
mkdir -p "$BACKEND_DIR"
mkdir -p "$FRONTEND_DIR"
print_info "Kopiere Backend..."
rsync -av --exclude 'node_modules' --exclude '.env' --delete "$CURRENT_DIR/backend/" "$BACKEND_DIR/"
print_info "Kopiere Frontend..."
rsync -av --exclude 'node_modules' --exclude 'dist' --exclude '.env*' --delete "$CURRENT_DIR/frontend/" "$FRONTEND_DIR/"
print_info "Kopiere Root-Dateien..."
rsync -av --exclude 'node_modules' --exclude '.git' --exclude 'frontend' --exclude 'backend' \
"$CURRENT_DIR"/*.{sh,conf,md,js,json,service} "$PROJECT_DIR/" 2>/dev/null || true
print_success "Projekt-Dateien kopiert!"
}
setup_backend() {
print_header "Setup Backend"
cd $BACKEND_DIR
print_info "Installiere Backend-Dependencies..."
# npm Konfiguration verhärten (weniger Hänger/Output)
npm config set fund false >/dev/null 2>&1 || true
npm config set audit false >/dev/null 2>&1 || true
npm config set progress false >/dev/null 2>&1 || true
npm config set loglevel warn >/dev/null 2>&1 || true
# Backend braucht alle Dependencies (auch dev für Build-Tools)
npm install --no-audit --no-fund --loglevel=warn
if [ ! -f .env ]; then
print_warning ".env Datei nicht gefunden!"
if [ -f env.production.template ]; then
print_info "Kopiere Template..."
cp env.production.template .env
print_warning "WICHTIG: Bitte bearbeite $BACKEND_DIR/.env und passe die Werte an!"
read -p "Drücke Enter wenn du fertig bist..."
else
print_error "Auch env.production.template nicht gefunden!"
exit 1
fi
else
print_success ".env bereits vorhanden"
fi
print_success "Backend Setup abgeschlossen!"
}
setup_frontend() {
print_header "Setup Frontend"
cd $FRONTEND_DIR
print_info "Installiere Frontend-Dependencies..."
# npm Konfiguration verhärten
npm config set fund false >/dev/null 2>&1 || true
npm config set audit false >/dev/null 2>&1 || true
npm config set progress false >/dev/null 2>&1 || true
npm config set loglevel warn >/dev/null 2>&1 || true
# Frontend braucht dev-Dependencies für den Build (vite, etc.)
npm install --no-audit --no-fund --loglevel=warn
# .env.production erstellen falls nicht vorhanden
if [ ! -f ".env.production" ]; then
print_info "Erstelle .env.production..."
cat > .env.production << 'EOF'
# TimeClock v3 - Frontend Production Environment
# API Base URL (relativ, da Apache als Proxy dient)
VITE_API_URL=/api
EOF
print_success ".env.production erstellt"
else
print_success ".env.production bereits vorhanden"
fi
# .env.development erstellen falls nicht vorhanden (für lokale Entwicklung)
if [ ! -f ".env.development" ]; then
print_info "Erstelle .env.development..."
cat > .env.development << 'EOF'
# TimeClock v3 - Frontend Development Environment
VITE_API_URL=http://localhost:3010/api
EOF
print_success ".env.development erstellt"
fi
# Prüfe ob api.js existiert
if [ ! -f "src/config/api.js" ]; then
print_warning "src/config/api.js fehlt! Bitte git pull ausführen."
exit 1
fi
# Alte dist/ löschen für sauberen Build
print_info "Lösche alten Build..."
rm -rf dist/
print_info "Erstelle Produktions-Build..."
npm run build
if [ ! -d "dist" ]; then
print_error "Build fehlgeschlagen - dist/ Verzeichnis nicht gefunden!"
exit 1
fi
# Prüfe ob localhost:3010 noch im Build ist
if grep -r "localhost:3010" dist/ > /dev/null 2>&1; then
print_warning "⚠️ localhost:3010 noch im Build gefunden - eventuell falsches .env verwendet"
print_info "Prüfe .env.production: $(cat .env.production 2>/dev/null || echo 'nicht gefunden')"
else
print_success "✅ Build verwendet korrekte API-URL"
fi
print_success "Frontend Build erstellt!"
}
setup_webserver() {
if [ "$WEBSERVER" = "nginx" ]; then
print_header "Setup Nginx"
WEBSERVER_CONF="/etc/nginx/sites-available/$DOMAIN"
if [ ! -f "$WEBSERVER_CONF" ]; then
print_info "Kopiere Nginx-Konfiguration..."
sudo cp "$PROJECT_DIR/nginx.conf" "$WEBSERVER_CONF"
print_info "Aktiviere Site..."
sudo ln -sf "$WEBSERVER_CONF" "/etc/nginx/sites-enabled/$DOMAIN"
print_info "Teste Nginx-Konfiguration..."
sudo nginx -t
print_info "Lade Nginx neu..."
sudo systemctl reload nginx
print_success "Nginx konfiguriert!"
else
print_warning "Nginx-Konfiguration existiert bereits"
read -p "Überschreiben? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
sudo cp "$PROJECT_DIR/nginx.conf" "$WEBSERVER_CONF"
sudo nginx -t && sudo systemctl reload nginx
print_success "Nginx-Konfiguration aktualisiert!"
fi
fi
else
print_header "Setup Apache2"
WEBSERVER_CONF="/etc/apache2/sites-available/$DOMAIN.conf"
if [ ! -f "$WEBSERVER_CONF" ]; then
print_info "Kopiere Apache2-Konfiguration..."
sudo cp "$PROJECT_DIR/apache2.conf" "$WEBSERVER_CONF"
print_info "Aktiviere Site..."
sudo a2ensite "$DOMAIN"
# Deaktiviere Default-Site (optional)
if [ -f "/etc/apache2/sites-enabled/000-default.conf" ]; then
print_info "Deaktiviere Default-Site..."
sudo a2dissite 000-default
fi
print_info "Teste Apache2-Konfiguration..."
sudo apache2ctl configtest
print_info "Lade Apache2 neu..."
sudo systemctl reload apache2
print_success "Apache2 konfiguriert!"
else
print_warning "Apache2-Konfiguration existiert bereits"
read -p "Überschreiben? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
sudo cp "$PROJECT_DIR/apache2.conf" "$WEBSERVER_CONF"
sudo apache2ctl configtest && sudo systemctl reload apache2
print_success "Apache2-Konfiguration aktualisiert!"
fi
fi
fi
}
setup_ssl() {
print_header "Setup SSL-Zertifikat"
print_info "Prüfe ob Zertifikat bereits existiert..."
if [ -d "/etc/letsencrypt/live/$DOMAIN" ]; then
print_success "SSL-Zertifikat bereits vorhanden"
return
fi
print_warning "Stelle sicher, dass $DOMAIN auf diesen Server zeigt!"
read -p "Fortfahren? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
print_info "SSL-Setup übersprungen"
return
fi
print_info "Erstelle SSL-Zertifikat mit Let's Encrypt..."
if [ "$WEBSERVER" = "nginx" ]; then
sudo certbot --nginx -d $DOMAIN
else
sudo certbot --apache -d $DOMAIN
fi
print_success "SSL-Zertifikat erstellt!"
}
setup_backend_service() {
print_header "Setup Backend-Service"
if [ "$USE_PM2" = true ]; then
print_info "Starte Backend mit PM2..."
cd $BACKEND_DIR
pm2 delete $SERVICE_NAME 2>/dev/null || true
pm2 start src/index.js --name $SERVICE_NAME --env production
pm2 save
print_info "Richte PM2 Auto-Start ein..."
sudo env PATH=$PATH:/usr/bin pm2 startup systemd -u $USER --hp $HOME
print_success "Backend läuft mit PM2!"
else
print_info "Installiere systemd-Service..."
sudo cp "$PROJECT_DIR/timeclock.service" /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable $SERVICE_NAME
sudo systemctl start $SERVICE_NAME
print_success "Backend läuft mit systemd!"
fi
}
setup_firewall() {
print_header "Setup Firewall"
if ! check_command ufw; then
print_warning "UFW nicht installiert, überspringe Firewall-Setup"
return
fi
print_info "Konfiguriere UFW..."
sudo ufw allow ssh
if [ "$WEBSERVER" = "nginx" ]; then
sudo ufw allow 'Nginx Full'
else
sudo ufw allow 'Apache Full'
fi
if ! sudo ufw status | grep -q "Status: active"; then
print_warning "UFW ist nicht aktiv"
read -p "UFW aktivieren? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
sudo ufw --force enable
print_success "UFW aktiviert!"
fi
else
print_success "UFW bereits konfiguriert"
fi
}
# =============================================================================
# Update - Aktualisierung einer bestehenden Installation
# =============================================================================
do_update() {
print_header "Update $PROJECT_NAME"
CURRENT_DIR=$(pwd)
# Prüfe ob wir im Quell-Verzeichnis sind
if [ ! -f "deploy.sh" ] || [ ! -d "backend" ] || [ ! -d "frontend" ]; then
print_error "Führe das Script aus dem Projekt-Verzeichnis aus!"
print_info "Aktuell in: $CURRENT_DIR"
print_info "Erwarte: backend/, frontend/ und deploy.sh im aktuellen Verzeichnis"
exit 1
fi
print_info "Quell-Verzeichnis: $CURRENT_DIR"
print_info "Ziel-Verzeichnis: $PROJECT_DIR"
# Backup erstellen
do_backup
# Kopiere aktualisierte Dateien
print_header "Kopiere aktualisierte Dateien"
print_info "Kopiere Backend..."
rsync -av --exclude 'node_modules' --exclude '.env' --delete "$CURRENT_DIR/backend/" "$BACKEND_DIR/"
print_info "Kopiere Frontend..."
rsync -av --exclude 'node_modules' --exclude 'dist' --exclude '.env*' --delete "$CURRENT_DIR/frontend/" "$FRONTEND_DIR/"
print_info "Kopiere Konfigurations-Dateien..."
rsync -av "$CURRENT_DIR"/*.{sh,conf,md,service} "$PROJECT_DIR/" 2>/dev/null || true
# Backend aktualisieren
print_info "Aktualisiere Backend Dependencies..."
cd $BACKEND_DIR
# Prüfe ob package-lock.json existiert
if [ ! -f "package-lock.json" ]; then
print_warning "package-lock.json fehlt! Verwende npm install statt npm ci"
npm install --no-audit --no-fund --loglevel=warn
else
npm config set fund false >/dev/null 2>&1 || true
npm config set audit false >/dev/null 2>&1 || true
npm config set progress false >/dev/null 2>&1 || true
npm config set loglevel warn >/dev/null 2>&1 || true
# Backend braucht alle Dependencies (auch dev für Build-Tools)
if ! npm ci --no-audit --no-fund --loglevel=warn 2>&1; then
print_warning "npm ci fehlgeschlagen. Fallback auf npm install..."
rm -rf node_modules
npm install --no-audit --no-fund --loglevel=warn || {
print_error "npm install (Backend Update) fehlgeschlagen"
exit 1
}
fi
fi
# Frontend aktualisieren
print_info "Aktualisiere Frontend..."
cd $FRONTEND_DIR
# .env.production prüfen/erstellen
if [ ! -f ".env.production" ]; then
print_info "Erstelle .env.production..."
cat > .env.production << 'EOF'
# TimeClock v3 - Frontend Production Environment
VITE_API_URL=/api
EOF
fi
# Prüfe ob package-lock.json existiert
if [ ! -f "package-lock.json" ]; then
print_warning "package-lock.json fehlt! Verwende npm install statt npm ci"
npm install --no-audit --no-fund --loglevel=warn
else
npm config set fund false >/dev/null 2>&1 || true
npm config set audit false >/dev/null 2>&1 || true
npm config set progress false >/dev/null 2>&1 || true
npm config set loglevel warn >/dev/null 2>&1 || true
# Frontend braucht dev-Dependencies für den Build (vite, etc.)
if ! npm ci --no-audit --no-fund --loglevel=warn 2>&1; then
print_warning "npm ci fehlgeschlagen. Fallback auf npm install..."
rm -rf node_modules
npm install --no-audit --no-fund --loglevel=warn || {
print_error "npm install (Frontend Update) fehlgeschlagen"
exit 1
}
fi
fi
# Sauberer Build
rm -rf dist/
npm run build
# Prüfe Build
if grep -r "localhost:3010" dist/ > /dev/null 2>&1; then
print_warning "⚠️ localhost:3010 noch im Build - bitte prüfen"
fi
# Service neu starten
restart_backend
# Apache Cache leeren
if [ "$WEBSERVER" = "apache2" ]; then
sudo systemctl reload apache2
else
sudo systemctl reload nginx
fi
print_success "Update abgeschlossen!"
}
# =============================================================================
# Backup & Rollback
# =============================================================================
do_backup() {
print_header "Erstelle Backup"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
print_info "Erstelle Datenbank-Backup..."
# Lese DB-Credentials aus .env
DB_NAME=$(grep DB_NAME $BACKEND_DIR/.env | cut -d '=' -f2)
DB_USER=$(grep DB_USER $BACKEND_DIR/.env | cut -d '=' -f2)
DB_PASSWORD=$(grep DB_PASSWORD $BACKEND_DIR/.env | cut -d '=' -f2)
# Verwende --no-tablespaces um PROCESS-Privileg zu vermeiden
mysqldump --no-tablespaces -u $DB_USER -p"$DB_PASSWORD" $DB_NAME | gzip > "$BACKUP_DIR/${PROJECT_NAME,,}_$TIMESTAMP.sql.gz" || {
print_warning "mysqldump mit --no-tablespaces fehlgeschlagen. Erzeuge nur Code-Backup."
}
print_info "Erstelle Code-Backup..."
tar -czf "$BACKUP_DIR/${PROJECT_NAME,,}_code_$TIMESTAMP.tar.gz" -C $(dirname $PROJECT_DIR) $(basename $PROJECT_DIR)
# Alte Backups löschen (älter als 30 Tage)
find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete
find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete
print_success "Backup erstellt: $TIMESTAMP"
}
do_rollback() {
print_header "Rollback zu vorheriger Version"
print_warning "Rollback wird die letzte Code-Version wiederherstellen"
read -p "Fortfahren? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
print_info "Rollback abgebrochen"
return
fi
# Finde letztes Code-Backup
LAST_BACKUP=$(ls -t $BACKUP_DIR/${PROJECT_NAME,,}_code_*.tar.gz 2>/dev/null | head -n1)
if [ -z "$LAST_BACKUP" ]; then
print_error "Kein Backup gefunden!"
exit 1
fi
print_info "Stelle wieder her: $LAST_BACKUP"
# Aktuellen Code sichern
mv $PROJECT_DIR "${PROJECT_DIR}_rollback_backup_$(date +%Y%m%d_%H%M%S)"
# Backup wiederherstellen
tar -xzf "$LAST_BACKUP" -C $(dirname $PROJECT_DIR)
# Services neu starten
restart_backend
print_success "Rollback abgeschlossen!"
}
# =============================================================================
# Service Management
# =============================================================================
restart_backend() {
print_info "Starte Backend neu..."
if [ "$USE_PM2" = true ]; then
pm2 restart $SERVICE_NAME
else
sudo systemctl restart $SERVICE_NAME
fi
print_success "Backend neu gestartet!"
}
show_status() {
print_header "Service Status"
if [ "$USE_PM2" = true ]; then
pm2 status $SERVICE_NAME
echo ""
pm2 info $SERVICE_NAME
else
sudo systemctl status $SERVICE_NAME
fi
echo ""
if [ "$WEBSERVER" = "nginx" ]; then
print_info "Nginx Status:"
sudo systemctl status nginx --no-pager | head -n 10
else
print_info "Apache2 Status:"
sudo systemctl status apache2 --no-pager | head -n 10
fi
echo ""
print_info "SSL-Zertifikat:"
sudo certbot certificates | grep -A 5 $DOMAIN || print_warning "Kein Zertifikat gefunden"
}
show_logs() {
print_header "Logs"
echo "1) Backend-Logs"
echo "2) Webserver Access-Logs"
echo "3) Webserver Error-Logs"
echo "4) Alle Logs (follow)"
read -p "Auswahl (1-4): " choice
if [ "$WEBSERVER" = "nginx" ]; then
ACCESS_LOG="/var/log/nginx/stechuhr3.access.log"
ERROR_LOG="/var/log/nginx/stechuhr3.error.log"
else
ACCESS_LOG="/var/log/apache2/stechuhr3-access.log"
ERROR_LOG="/var/log/apache2/stechuhr3-error.log"
fi
case $choice in
1)
if [ "$USE_PM2" = true ]; then
pm2 logs $SERVICE_NAME
else
sudo journalctl -u $SERVICE_NAME -f
fi
;;
2)
sudo tail -f "$ACCESS_LOG"
;;
3)
sudo tail -f "$ERROR_LOG"
;;
4)
if [ "$USE_PM2" = true ]; then
pm2 logs $SERVICE_NAME &
PM2_PID=$!
else
sudo journalctl -u $SERVICE_NAME -f &
JOURNAL_PID=$!
fi
if [ "$WEBSERVER" = "nginx" ]; then
sudo tail -f /var/log/nginx/stechuhr3.*.log
else
sudo tail -f /var/log/apache2/stechuhr3-*.log
fi
;;
*)
print_error "Ungültige Auswahl"
;;
esac
}
# =============================================================================
# Vollständige Installation
# =============================================================================
do_install() {
print_header "$PROJECT_NAME - Vollständige Installation"
check_root
print_warning "Diese Installation wird folgendes tun:"
echo " - System-Abhängigkeiten installieren"
echo " - Projekt nach $PROJECT_DIR kopieren"
echo " - Backend und Frontend einrichten"
echo " - Nginx konfigurieren"
echo " - SSL-Zertifikat erstellen"
echo " - Backend-Service starten"
echo " - Firewall konfigurieren"
echo ""
read -p "Fortfahren? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
print_info "Installation abgebrochen"
exit 0
fi
install_dependencies
setup_directories
copy_project_files
setup_backend
setup_frontend
setup_webserver
setup_ssl
setup_backend_service
setup_firewall
print_header "Installation abgeschlossen! 🎉"
print_success "Deine TimeClock-App läuft jetzt auf https://$DOMAIN"
echo ""
print_info "Nützliche Befehle:"
echo " ./deploy.sh status - Zeige Service-Status"
echo " ./deploy.sh logs - Zeige Logs"
echo " ./deploy.sh update - Update durchführen"
echo " ./deploy.sh backup - Backup erstellen"
echo ""
}
# =============================================================================
# Hauptprogramm
# =============================================================================
show_help() {
cat << EOF
$PROJECT_NAME v3 - Deployment Script
Verwendung: $0 [OPTION]
Optionen:
install Erste Installation (inkl. System-Setup)
update Update einer bestehenden Installation
rollback Rollback zur vorherigen Version
backup Erstelle Backup der Datenbank
status Zeige Status der Services
logs Zeige Logs
help Zeige diese Hilfe
Beispiele:
$0 install # Erste Installation
$0 update # Update durchführen
$0 backup # Backup erstellen
$0 status # Status anzeigen
EOF
}
# Hauptlogik
case "${1:-help}" in
install)
do_install
;;
update)
do_update
;;
rollback)
do_rollback
;;
backup)
do_backup
;;
status)
show_status
;;
logs)
show_logs
;;
help|--help|-h)
show_help
;;
*)
print_error "Unbekannte Option: $1"
echo ""
show_help
exit 1
;;
esac
exit 0