#!/bin/bash # ============================================================================= # LibreBooking n8n Node - Docker Integration Script # ============================================================================= # Automatische Integration des LibreBooking Nodes in bestehende n8n Docker-Installationen # # Verwendung: ./install-docker.sh [OPTIONS] # # Optionen: # -p, --path PATH Pfad zur n8n Docker-Installation (Standard: aktuelles Verzeichnis) # -b, --build Node im Container bauen statt vorgebaut kopieren # -f, --force Bestehende Installation überschreiben # -h, --help Diese Hilfe anzeigen # # ============================================================================= set -e # Farben für Ausgabe RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Standardwerte N8N_PATH="." FORCE=false BUILD_IN_CONTAINER=false SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # Hilfsfunktionen print_info() { echo -e "${BLUE}[INFO]${NC} $1" } print_success() { echo -e "${GREEN}[✓]${NC} $1" } print_warning() { echo -e "${YELLOW}[!]${NC} $1" } print_error() { echo -e "${RED}[FEHLER]${NC} $1" } show_help() { echo "LibreBooking n8n Node - Docker Integration Script" echo "" echo "Verwendung: $0 [OPTIONS]" echo "" echo "Optionen:" echo " -p, --path PATH Pfad zur n8n Docker-Installation" echo " -b, --build Node im Container bauen" echo " -f, --force Bestehende Installation überschreiben" echo " -h, --help Diese Hilfe anzeigen" echo "" echo "Beispiele:" echo " $0 # Installation im aktuellen Verzeichnis" echo " $0 -p /opt/n8n # Installation in /opt/n8n" echo " $0 -f -p /home/user/n8n # Installation mit Überschreiben" exit 0 } # Argumente parsen while [[ $# -gt 0 ]]; do case $1 in -p|--path) N8N_PATH="$2" shift 2 ;; -b|--build) BUILD_IN_CONTAINER=true shift ;; -f|--force) FORCE=true shift ;; -h|--help) show_help ;; *) print_error "Unbekannte Option: $1" show_help ;; esac done echo "" echo "=========================================" echo " LibreBooking n8n Node - Docker Setup" echo "=========================================" echo "" # ============================================================================= # Voraussetzungen prüfen # ============================================================================= print_info "Prüfe Voraussetzungen..." # Docker prüfen if ! command -v docker &> /dev/null; then print_error "Docker ist nicht installiert!" echo " Bitte installieren Sie Docker: https://docs.docker.com/get-docker/" exit 1 fi print_success "Docker gefunden: $(docker --version)" # Docker Compose prüfen - v2 bevorzugen detect_compose_command() { # Zuerst docker compose (v2/Plugin) prüfen - bevorzugt if docker compose version &> /dev/null 2>&1; then COMPOSE_CMD="docker compose" COMPOSE_VERSION="v2" return 0 fi # Dann docker-compose (v1) prüfen if command -v docker-compose &> /dev/null; then # Prüfen ob es tatsächlich funktioniert (distutils Problem bei Python 3.12) if docker-compose --version &> /dev/null 2>&1; then COMPOSE_CMD="docker-compose" COMPOSE_VERSION="v1" return 0 else # docker-compose existiert aber funktioniert nicht print_warning "docker-compose (v1) ist installiert, funktioniert aber nicht!" print_warning "Dies liegt wahrscheinlich am fehlenden 'distutils' Modul (Python 3.12+)" echo "" echo " Mögliche Lösungen:" echo " 1. Docker Compose v2 installieren (empfohlen):" echo " sudo apt-get update && sudo apt-get install docker-compose-plugin" echo "" echo " 2. distutils für Python installieren (Workaround):" echo " sudo apt-get install python3-distutils" echo " # Oder für neuere Systeme:" echo " pip3 install setuptools" echo "" echo " Siehe TROUBLESHOOTING.md für weitere Details." echo "" return 1 fi fi return 1 } # Compose Command ermitteln if detect_compose_command; then if [ "$COMPOSE_VERSION" = "v2" ]; then print_success "Docker Compose v2 (Plugin) gefunden: $(docker compose version --short 2>/dev/null || docker compose version)" else print_success "docker-compose v1 gefunden: $(docker-compose --version)" print_warning "Empfehlung: Upgrade zu Docker Compose v2 für bessere Kompatibilität" fi else print_error "Docker Compose ist nicht installiert oder funktioniert nicht!" echo "" echo " Installation von Docker Compose v2 (empfohlen):" echo " sudo apt-get update && sudo apt-get install docker-compose-plugin" echo "" echo " Oder siehe: https://docs.docker.com/compose/install/" echo "" echo " Alternativ: Verwenden Sie install-docker-manual.sh für Installation ohne docker-compose" exit 1 fi # Hilfsfunktion für Compose-Befehle run_compose() { $COMPOSE_CMD "$@" } # ============================================================================= # Funktion: Prüft ob ein Verzeichnis read-only ist # ============================================================================= check_readonly() { local dir="$1" local test_file="$dir/.write_test_$$" # Versuche eine Test-Datei zu erstellen if touch "$test_file" 2>/dev/null; then rm -f "$test_file" 2>/dev/null return 0 # Schreibbar else return 1 # Read-only fi } print_readonly_warning() { local dir="$1" print_error "Das Verzeichnis '$dir' ist read-only!" echo "" echo " Das custom-nodes Verzeichnis benötigt Schreibrechte für:" echo " - npm install (Dependencies)" echo " - npm run build (Kompilierung)" echo "" echo " LÖSUNGEN:" echo "" echo " 1. Volume OHNE :ro mounten (empfohlen):" echo " volumes:" echo " - ./custom-nodes:/home/node/.n8n/custom/n8n-nodes-librebooking" echo " # NICHT: - ./custom-nodes:/...:ro" 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. Berechtigungen prüfen:" echo " ls -la $dir" echo " sudo chown -R 1000:1000 $dir" echo "" echo " Siehe: TROUBLESHOOTING.md und SECURITY.md" } # Zielpfad prüfen if [ ! -d "$N8N_PATH" ]; then print_error "Verzeichnis existiert nicht: $N8N_PATH" exit 1 fi N8N_PATH=$(cd "$N8N_PATH" && pwd) print_info "Zielverzeichnis: $N8N_PATH" # docker-compose.yml prüfen if [ ! -f "$N8N_PATH/docker-compose.yml" ] && [ ! -f "$N8N_PATH/docker-compose.yaml" ]; then print_warning "Keine docker-compose.yml gefunden in $N8N_PATH" echo "" read -p "Soll eine Beispiel-Konfiguration erstellt werden? (j/n): " CREATE_EXAMPLE if [[ "$CREATE_EXAMPLE" =~ ^[jJyY]$ ]]; then print_info "Kopiere Beispiel-Konfiguration..." cp "$SCRIPT_DIR/docker-compose.example.yml" "$N8N_PATH/docker-compose.yml" cp "$SCRIPT_DIR/.env.docker" "$N8N_PATH/.env" print_success "Beispiel-Konfiguration erstellt" print_warning "Bitte $N8N_PATH/.env anpassen!" else print_error "Abbruch: Keine docker-compose.yml vorhanden" exit 1 fi fi # ============================================================================= # n8n Status prüfen # ============================================================================= print_info "Prüfe n8n Container Status..." cd "$N8N_PATH" N8N_RUNNING=false if $COMPOSE_CMD ps 2>/dev/null | grep -q "n8n.*Up"; then N8N_RUNNING=true print_success "n8n Container läuft" else print_warning "n8n Container läuft nicht (wird später gestartet)" fi # ============================================================================= # Custom Nodes Verzeichnis vorbereiten # ============================================================================= print_info "Bereite Custom Nodes Verzeichnis vor..." CUSTOM_NODES_DIR="$N8N_PATH/custom-nodes" # Prüfen ob bereits installiert if [ -d "$CUSTOM_NODES_DIR" ]; then if [ "$FORCE" = true ]; then print_warning "Bestehendes custom-nodes Verzeichnis wird überschrieben" rm -rf "$CUSTOM_NODES_DIR" else print_warning "custom-nodes Verzeichnis existiert bereits" read -p "Überschreiben? (j/n): " OVERWRITE if [[ "$OVERWRITE" =~ ^[jJyY]$ ]]; then rm -rf "$CUSTOM_NODES_DIR" else print_info "Behalte bestehendes Verzeichnis" fi fi fi # Custom Nodes kopieren if [ ! -d "$CUSTOM_NODES_DIR" ]; then cp -r "$SCRIPT_DIR/custom-nodes" "$CUSTOM_NODES_DIR" print_success "Custom Nodes kopiert nach: $CUSTOM_NODES_DIR" fi # Prüfe ob Verzeichnis schreibbar ist if ! check_readonly "$CUSTOM_NODES_DIR"; then print_readonly_warning "$CUSTOM_NODES_DIR" echo "" read -p "Trotzdem fortfahren? (j/n): " CONTINUE_RO if [[ ! "$CONTINUE_RO" =~ ^[jJyY]$ ]]; then print_error "Abbruch wegen read-only Verzeichnis" exit 1 fi print_warning "Fortsetzen trotz read-only - npm install wird fehlschlagen!" fi # ============================================================================= # Node bauen (wenn nicht bereits gebaut) # ============================================================================= if [ ! -d "$CUSTOM_NODES_DIR/dist" ] || [ "$BUILD_IN_CONTAINER" = true ]; then print_info "Baue LibreBooking Node..." cd "$CUSTOM_NODES_DIR" # Prüfen ob node/npm vorhanden if command -v npm &> /dev/null; then npm install 2>/dev/null || print_warning "npm install hatte Warnungen" npm run build 2>/dev/null || { print_warning "Build fehlgeschlagen, versuche alternativen Ansatz..." # Manueller Build npx tsc 2>/dev/null || true mkdir -p dist/nodes/LibreBooking dist/nodes/LibreBookingTrigger cp nodes/LibreBooking/*.svg dist/nodes/LibreBooking/ 2>/dev/null || true cp nodes/LibreBookingTrigger/*.svg dist/nodes/LibreBookingTrigger/ 2>/dev/null || true } print_success "Node erfolgreich gebaut" else print_warning "npm nicht gefunden - Node wird beim Container-Start gebaut" print_info "Erstelle Build-Skript für Container..." cat > "$CUSTOM_NODES_DIR/build.sh" << 'BUILDEOF' #!/bin/sh cd /home/node/.n8n/custom/n8n-nodes-librebooking npm install npm run build BUILDEOF chmod +x "$CUSTOM_NODES_DIR/build.sh" fi cd "$N8N_PATH" fi # ============================================================================= # Docker Compose Override erstellen/aktualisieren # ============================================================================= print_info "Erstelle docker-compose.override.yml..." OVERRIDE_FILE="$N8N_PATH/docker-compose.override.yml" if [ -f "$OVERRIDE_FILE" ]; then print_warning "docker-compose.override.yml existiert bereits" # Prüfen ob LibreBooking bereits konfiguriert if grep -q "n8n-nodes-librebooking" "$OVERRIDE_FILE"; then print_success "LibreBooking bereits in override.yml konfiguriert" else print_info "Füge LibreBooking Konfiguration hinzu..." # Backup erstellen cp "$OVERRIDE_FILE" "${OVERRIDE_FILE}.backup" # Hinzufügen (vereinfacht - für komplexe Fälle manuell anpassen) cat >> "$OVERRIDE_FILE" << 'OVERRIDEEOF' # LibreBooking Node (automatisch hinzugefügt) # Falls Konflikte auftreten, bitte manuell anpassen # Siehe DOCKER-INTEGRATION.md für Details OVERRIDEEOF print_warning "Bitte $OVERRIDE_FILE manuell prüfen!" fi else # Neue Override-Datei erstellen cat > "$OVERRIDE_FILE" << 'OVERRIDEEOF' # Docker Compose Override für LibreBooking n8n Node # Automatisch generiert von install-docker.sh version: '3.8' services: n8n: volumes: # LibreBooking Custom Node - ./custom-nodes:/home/node/.n8n/custom/n8n-nodes-librebooking:ro environment: # Custom Nodes aktivieren - N8N_CUSTOM_EXTENSIONS=/home/node/.n8n/custom - N8N_COMMUNITY_NODES_ENABLED=true OVERRIDEEOF print_success "docker-compose.override.yml erstellt" fi # ============================================================================= # Berechtigungen setzen # ============================================================================= print_info "Setze Berechtigungen..." # n8n läuft oft als node User mit UID 1000 if [ "$(id -u)" = "0" ]; then chown -R 1000:1000 "$CUSTOM_NODES_DIR" 2>/dev/null || print_warning "Konnte Berechtigungen nicht setzen" else # Versuche mit sudo falls verfügbar if command -v sudo &> /dev/null; then sudo chown -R 1000:1000 "$CUSTOM_NODES_DIR" 2>/dev/null || print_warning "Konnte Berechtigungen nicht setzen (sudo fehlgeschlagen)" fi fi print_success "Berechtigungen konfiguriert" # ============================================================================= # Container neustarten # ============================================================================= echo "" read -p "Soll der n8n Container jetzt neu gestartet werden? (j/n): " RESTART if [[ "$RESTART" =~ ^[jJyY]$ ]]; then print_info "Starte n8n Container neu..." if [ "$N8N_RUNNING" = true ]; then $COMPOSE_CMD restart n8n 2>/dev/null || $COMPOSE_CMD restart else $COMPOSE_CMD up -d n8n 2>/dev/null || $COMPOSE_CMD up -d fi # Warten bis Container bereit print_info "Warte auf Container-Start..." sleep 5 # Status prüfen if $COMPOSE_CMD ps | grep -q "n8n.*Up"; then print_success "n8n Container läuft!" else print_warning "Container-Status unklar - bitte manuell prüfen" fi else print_info "Container nicht neu gestartet" echo " Führen Sie später aus: cd $N8N_PATH && $COMPOSE_CMD restart" fi # ============================================================================= # Abschluss # ============================================================================= echo "" echo "=========================================" print_success "Installation abgeschlossen!" echo "=========================================" echo "" echo "Nächste Schritte:" echo "1. Öffnen Sie n8n in Ihrem Browser" echo "2. Gehen Sie zu: Settings > Community Nodes" echo "3. Der 'LibreBooking' Node sollte sichtbar sein" echo "4. Erstellen Sie neue Credentials für LibreBooking" echo "" echo "Bei Problemen siehe: DOCKER-INTEGRATION.md" echo ""