455 lines
15 KiB
Bash
Executable File
455 lines
15 KiB
Bash
Executable File
#!/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 ""
|