#!/bin/bash # ============================================================================ # fix-node-installation.sh - All-in-One Lösung für Node-Installation im Container # Führt alle Schritte automatisch aus (auf dem HOST ausführen!) # ============================================================================ set -e # Farben RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # Standard-Werte CONTAINER_NAME="n8n" CONTAINER_PATH="/home/node/.n8n/custom/n8n-nodes-librebooking" SKIP_RESTART=false VERBOSE=false echo -e "${BLUE}============================================${NC}" echo -e "${BLUE} LibreBooking Node - Auto-Fix Installation${NC}" echo -e "${BLUE}============================================${NC}" echo "" # Hilfe anzeigen show_help() { echo "Verwendung: $0 [OPTIONEN]" echo "" echo "Dieses Skript installiert den LibreBooking Node automatisch im Docker Container." echo "" echo "Optionen:" echo " -c, --container NAME Container-Name (Standard: n8n)" echo " -p, --path PATH Pfad im Container (Standard: /home/node/.n8n/custom/n8n-nodes-librebooking)" echo " -n, --no-restart Container nicht neustarten" echo " -v, --verbose Ausführliche Ausgabe" echo " -h, --help Diese Hilfe anzeigen" echo "" echo "Beispiele:" echo " $0 # Standard-Installation" echo " $0 -c mein-n8n # Anderer Container-Name" echo " $0 -p /opt/n8n/custom-nodes # Anderer Pfad" echo " $0 -n # Ohne Neustart" exit 0 } # Parameter parsen while [[ $# -gt 0 ]]; do case $1 in -c|--container) CONTAINER_NAME="$2" shift 2 ;; -p|--path) CONTAINER_PATH="$2" shift 2 ;; -n|--no-restart) SKIP_RESTART=true shift ;; -v|--verbose) VERBOSE=true shift ;; -h|--help) show_help ;; *) echo -e "${RED}Unbekannte Option: $1${NC}" show_help ;; esac done log() { echo -e "${GREEN}[INFO]${NC} $1" } warn() { echo -e "${YELLOW}[WARN]${NC} $1" } error() { echo -e "${RED}[ERROR]${NC} $1" exit 1 } # Funktion: Prüft ob ein Verzeichnis im Container read-only ist check_readonly_container() { local container="$1" local dir="$2" local test_file="$dir/.write_test_$$" # Versuche eine Test-Datei im Container zu erstellen if docker exec "$container" touch "$test_file" 2>/dev/null; then docker exec "$container" rm -f "$test_file" 2>/dev/null return 0 # Schreibbar else return 1 # Read-only fi } print_readonly_solution() { echo "" echo -e "${RED}============================================${NC}" echo -e "${RED} PROBLEM: Read-only Volume erkannt!${NC}" echo -e "${RED}============================================${NC}" echo "" echo "Das custom-nodes Verzeichnis ist als read-only gemountet." echo "npm install und npm run build benötigen Schreibrechte." echo "" echo "LÖSUNGEN:" echo "" echo "1. Volume OHNE :ro mounten (empfohlen):" echo " In docker-compose.yml oder docker-compose.override.yml:" echo "" echo " volumes:" echo " - ./custom-nodes:/home/node/.n8n/custom/n8n-nodes-librebooking" echo " # ENTFERNEN: :ro am Ende!" echo "" echo "2. Auf dem Host bauen (für read-only Volumes):" echo " ./build-on-host.sh" echo " # Dann docker-compose.readonly.yml verwenden" echo "" echo "3. docker-compose.override.yml anpassen:" echo " cp docker-compose.override.yml docker-compose.override.yml.bak" echo " # Entfernen Sie ':ro' aus der Volume-Definition" echo "" echo "Siehe: TROUBLESHOOTING.md und DOCKER-INTEGRATION.md" } # Schritt 1: Docker prüfen log "Prüfe Docker..." if ! command -v docker &>/dev/null; then error "Docker ist nicht installiert!" fi # Schritt 2: Container prüfen log "Prüfe Container '$CONTAINER_NAME'..." if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then # Prüfe ob Container existiert aber nicht läuft if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then warn "Container '$CONTAINER_NAME' existiert aber läuft nicht." log "Starte Container..." docker start "$CONTAINER_NAME" sleep 3 else error "Container '$CONTAINER_NAME' nicht gefunden! Prüfen Sie den Namen mit: docker ps -a" fi fi log "Container '$CONTAINER_NAME' läuft ✓" # Schritt 3: Prüfe ob Pfad im Container existiert log "Prüfe Pfad im Container: $CONTAINER_PATH" if ! docker exec "$CONTAINER_NAME" test -d "$CONTAINER_PATH"; then # Versuche alternative Pfade ALTERNATIVE_PATHS=( "/home/node/.n8n/custom/n8n-nodes-librebooking" "/home/node/.n8n/custom" "/opt/n8n/custom-nodes" "/data/custom-nodes" ) FOUND_PATH="" for alt_path in "${ALTERNATIVE_PATHS[@]}"; do if docker exec "$CONTAINER_NAME" test -f "$alt_path/package.json" 2>/dev/null; then FOUND_PATH="$alt_path" break fi done if [ -n "$FOUND_PATH" ]; then warn "Angegebener Pfad nicht gefunden, verwende: $FOUND_PATH" CONTAINER_PATH="$FOUND_PATH" else error "Kein Custom-Node-Verzeichnis mit package.json gefunden!\n\n Bitte stellen Sie sicher, dass die Dateien korrekt kopiert wurden.\n Beispiel: docker cp custom-nodes/. $CONTAINER_NAME:/home/node/.n8n/custom/n8n-nodes-librebooking/" fi fi log "Pfad gefunden: $CONTAINER_PATH ✓" # Schritt 3.5: Prüfe ob Verzeichnis schreibbar ist (read-only Volume?) log "Prüfe Schreibrechte im Container..." if ! check_readonly_container "$CONTAINER_NAME" "$CONTAINER_PATH"; then print_readonly_solution exit 1 fi log "Schreibrechte vorhanden ✓" # Schritt 4: Skript in Container kopieren SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" if [ -f "$SCRIPT_DIR/install-in-container.sh" ]; then log "Kopiere install-in-container.sh in Container..." docker cp "$SCRIPT_DIR/install-in-container.sh" "$CONTAINER_NAME:/tmp/" else warn "install-in-container.sh nicht gefunden, erstelle inline..." fi # Schritt 5: npm install und build im Container log "Führe npm install aus..." if $VERBOSE; then docker exec -w "$CONTAINER_PATH" "$CONTAINER_NAME" npm install else if ! docker exec -w "$CONTAINER_PATH" "$CONTAINER_NAME" npm install 2>&1 | tail -5; then error "npm install fehlgeschlagen!" fi fi log "Dependencies installiert ✓" log "Führe npm run build aus..." if $VERBOSE; then docker exec -w "$CONTAINER_PATH" "$CONTAINER_NAME" npm run build else if ! docker exec -w "$CONTAINER_PATH" "$CONTAINER_NAME" npm run build 2>&1 | tail -10; then error "npm run build fehlgeschlagen!" fi fi log "Build erfolgreich ✓" # Schritt 6: Prüfe Ergebnis log "Prüfe Build-Ergebnis..." NODE_COUNT=$(docker exec "$CONTAINER_NAME" find "$CONTAINER_PATH/dist" -name "*.node.js" 2>/dev/null | wc -l) if [ "$NODE_COUNT" -gt 0 ]; then log "$NODE_COUNT Node-Datei(en) gefunden ✓" else error "Keine Node-Dateien nach Build gefunden!" fi # Schritt 7: Container neustarten if $SKIP_RESTART; then warn "Container-Neustart übersprungen (-n Option)" echo "" echo -e "${YELLOW}Bitte starten Sie den Container manuell neu:${NC}" echo " docker restart $CONTAINER_NAME" else log "Starte Container neu..." docker restart "$CONTAINER_NAME" log "Container neugestartet ✓" # Warte kurz auf Start sleep 5 fi # Schritt 8: Abschluss-Check (optional) echo "" echo -e "${GREEN}============================================${NC}" echo -e "${GREEN} Installation abgeschlossen!${NC}" echo -e "${GREEN}============================================${NC}" echo "" log "Der LibreBooking Node sollte jetzt in n8n verfügbar sein." echo "" echo "Nächste Schritte:" echo " 1. Öffnen Sie n8n im Browser" echo " 2. Erstellen Sie einen neuen Workflow" echo " 3. Suchen Sie nach 'LibreBooking'" echo "" echo "Falls der Node nicht erscheint:" echo " - Prüfen Sie die Logs: docker logs $CONTAINER_NAME 2>&1 | grep -i libre" echo " - Führen Sie das Check-Skript aus: docker exec $CONTAINER_NAME sh /tmp/check-installation.sh" echo "" # Optional: Check-Skript kopieren und ausführen if [ -f "$SCRIPT_DIR/check-installation.sh" ]; then docker cp "$SCRIPT_DIR/check-installation.sh" "$CONTAINER_NAME:/tmp/" echo "Tipp: Führen Sie für einen detaillierten Status aus:" echo " docker exec $CONTAINER_NAME sh /tmp/check-installation.sh" fi