Files
customer-installer/setup_botkonzept_lxc.sh

427 lines
13 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
set -Eeuo pipefail
# =====================================================
# BotKonzept LXC Setup Script
# =====================================================
# Erstellt eine LXC (ID 5000) mit:
# - n8n
# - PostgreSQL + botkonzept Datenbank
# - Alle benötigten Workflows
# - Vorkonfigurierte Credentials
# =====================================================
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Konfiguration
CTID=5010
HOSTNAME="botkonzept-n8n"
CORES=4
MEMORY=8192
SWAP=2048
DISK=100
STORAGE="local-zfs"
BRIDGE="vmbr0"
VLAN=90
IP="dhcp"
# 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
log_info() { echo -e "${BLUE}[INFO]${NC} $*"; }
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $*"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
log_error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }
# =====================================================
# Schritt 1: LXC erstellen
# =====================================================
log_info "Schritt 1: Erstelle LXC ${CTID}..."
# Prüfen ob LXC bereits existiert
if pct status ${CTID} &>/dev/null; then
log_warn "LXC ${CTID} existiert bereits. Soll sie gelöscht werden? (y/n)"
read -r answer
if [[ "$answer" == "y" ]]; then
log_info "Stoppe und lösche LXC ${CTID}..."
pct stop ${CTID} || true
pct destroy ${CTID}
else
log_error "Abbruch. Bitte andere CTID wählen."
fi
fi
# Debian 12 Template (bereits vorhanden)
TEMPLATE="debian-12-standard_12.12-1_amd64.tar.zst"
if [[ ! -f "/var/lib/vz/template/cache/${TEMPLATE}" ]]; then
log_info "Lade Debian 12 Template herunter..."
pveam download local ${TEMPLATE} || log_warn "Template-Download fehlgeschlagen, versuche fortzufahren..."
fi
log_info "Verwende Template: ${TEMPLATE}"
# LXC erstellen
log_info "Erstelle LXC Container..."
pct create ${CTID} local:vztmpl/${TEMPLATE} \
--hostname ${HOSTNAME} \
--cores ${CORES} \
--memory ${MEMORY} \
--swap ${SWAP} \
--rootfs ${STORAGE}:${DISK} \
--net0 name=eth0,bridge=${BRIDGE},tag=${VLAN},ip=${IP} \
--features nesting=1 \
--unprivileged 1 \
--onboot 1 \
--start 1
log_success "LXC ${CTID} erstellt und gestartet"
# Warten bis Container bereit ist
log_info "Warte auf Container-Start..."
sleep 10
# =====================================================
# Schritt 2: System aktualisieren
# =====================================================
log_info "Schritt 2: System aktualisieren..."
pct exec ${CTID} -- bash -c "
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get upgrade -y
DEBIAN_FRONTEND=noninteractive apt-get install -y \
curl \
wget \
git \
vim \
htop \
ca-certificates \
gnupg \
lsb-release \
postgresql \
postgresql-contrib \
build-essential \
postgresql-server-dev-15
"
log_success "System aktualisiert"
# =====================================================
# Schritt 2b: pgvector installieren
# =====================================================
log_info "Schritt 2b: pgvector installieren..."
pct exec ${CTID} -- bash -c "
cd /tmp
git clone --branch v0.7.4 https://github.com/pgvector/pgvector.git
cd pgvector
make
make install
cd /
rm -rf /tmp/pgvector
"
log_success "pgvector installiert"
# =====================================================
# Schritt 3: Docker installieren
# =====================================================
log_info "Schritt 3: Docker installieren..."
pct exec ${CTID} -- bash -c '
# Docker GPG Key
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
# Docker Repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
# Docker installieren
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Docker starten
systemctl enable docker
systemctl start docker
'
log_success "Docker installiert"
# =====================================================
# Schritt 4: PostgreSQL konfigurieren
# =====================================================
log_info "Schritt 4: PostgreSQL konfigurieren..."
# PostgreSQL Passwort generieren
PG_PASSWORD=$(openssl rand -base64 32 | tr -d '/+=' | head -c 24)
pct exec ${CTID} -- bash -c "
# PostgreSQL starten
systemctl enable postgresql
systemctl start postgresql
# Warten bis PostgreSQL bereit ist
sleep 5
# Postgres Passwort setzen
su - postgres -c \"psql -c \\\"ALTER USER postgres PASSWORD '${PG_PASSWORD}';\\\"\"
# Datenbank erstellen
su - postgres -c \"createdb botkonzept\"
# pgvector Extension aktivieren
su - postgres -c \"psql -d botkonzept -c 'CREATE EXTENSION IF NOT EXISTS vector;'\"
su - postgres -c \"psql -d botkonzept -c 'CREATE EXTENSION IF NOT EXISTS \\\"uuid-ossp\\\";'\"
"
log_success "PostgreSQL konfiguriert (Passwort: ${PG_PASSWORD})"
# =====================================================
# Schritt 5: Datenbank-Schema importieren
# =====================================================
log_info "Schritt 5: Datenbank-Schema importieren..."
# Schema-Datei in Container kopieren
pct push ${CTID} "${SCRIPT_DIR}/sql/botkonzept_schema.sql" /tmp/botkonzept_schema.sql
pct exec ${CTID} -- bash -c "
su - postgres -c 'psql -d botkonzept < /tmp/botkonzept_schema.sql'
rm /tmp/botkonzept_schema.sql
"
log_success "Datenbank-Schema importiert"
# =====================================================
# Schritt 6: n8n installieren
# =====================================================
log_info "Schritt 6: n8n installieren..."
# n8n Encryption Key generieren
N8N_ENCRYPTION_KEY=$(openssl rand -base64 32)
# Docker Compose Datei erstellen
pct exec ${CTID} -- bash -c "
mkdir -p /opt/n8n
cat > /opt/n8n/docker-compose.yml <<'COMPOSE_EOF'
version: '3.8'
services:
n8n:
image: n8nio/n8n:latest
container_name: n8n
restart: unless-stopped
ports:
- '5678:5678'
environment:
- N8N_HOST=0.0.0.0
- N8N_PORT=5678
- N8N_PROTOCOL=http
- WEBHOOK_URL=http://botkonzept-n8n:5678/
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- EXECUTIONS_DATA_SAVE_ON_ERROR=all
- EXECUTIONS_DATA_SAVE_ON_SUCCESS=all
- EXECUTIONS_DATA_SAVE_MANUAL_EXECUTIONS=true
- N8N_LOG_LEVEL=info
- N8N_LOG_OUTPUT=console
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=localhost
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=botkonzept
- DB_POSTGRESDB_USER=postgres
- DB_POSTGRESDB_PASSWORD=${PG_PASSWORD}
volumes:
- n8n_data:/home/node/.n8n
network_mode: host
volumes:
n8n_data:
COMPOSE_EOF
"
# n8n starten
pct exec ${CTID} -- bash -c "
cd /opt/n8n
docker compose up -d
"
log_success "n8n installiert und gestartet"
# Warten bis n8n bereit ist
log_info "Warte auf n8n-Start (30 Sekunden)..."
sleep 30
# =====================================================
# Schritt 7: n8n Owner Account erstellen (robuste Methode)
# =====================================================
log_info "Schritt 7: n8n Owner Account erstellen..."
N8N_OWNER_EMAIL="admin@botkonzept.de"
N8N_OWNER_PASSWORD=$(openssl rand -base64 16)
N8N_OWNER_FIRSTNAME="BotKonzept"
N8N_OWNER_LASTNAME="Admin"
# Methode 1: Via CLI im Container (bevorzugt)
log_info "Versuche Owner Account via CLI zu erstellen..."
pct exec ${CTID} -- bash -c "
cd /opt/n8n
docker exec -u node n8n n8n user-management:reset \
--email '${N8N_OWNER_EMAIL}' \
--password '${N8N_OWNER_PASSWORD}' \
--firstName '${N8N_OWNER_FIRSTNAME}' \
--lastName '${N8N_OWNER_LASTNAME}' 2>&1 || echo 'CLI method failed, trying REST API...'
"
# Methode 2: Via REST API (Fallback)
log_info "Versuche Owner Account via REST API zu erstellen..."
sleep 5
pct exec ${CTID} -- bash -c "
curl -sS -X POST 'http://127.0.0.1:5678/rest/owner/setup' \
-H 'Content-Type: application/json' \
-d '{
\"email\": \"${N8N_OWNER_EMAIL}\",
\"firstName\": \"${N8N_OWNER_FIRSTNAME}\",
\"lastName\": \"${N8N_OWNER_LASTNAME}\",
\"password\": \"${N8N_OWNER_PASSWORD}\"
}' 2>&1 || echo 'REST API method also failed - manual setup may be required'
"
log_success "n8n Owner Account Setup abgeschlossen (prüfen Sie die n8n UI)"
# =====================================================
# Schritt 8: Workflows vorbereiten
# =====================================================
log_info "Schritt 8: Workflows vorbereiten..."
# Workflows in Container kopieren
pct push ${CTID} "${SCRIPT_DIR}/BotKonzept-Customer-Registration-Workflow.json" /opt/n8n/registration-workflow.json
pct push ${CTID} "${SCRIPT_DIR}/BotKonzept-Trial-Management-Workflow.json" /opt/n8n/trial-workflow.json
log_success "Workflows kopiert nach /opt/n8n/"
# =====================================================
# Schritt 9: Systemd Service für n8n
# =====================================================
log_info "Schritt 9: Systemd Service erstellen..."
pct exec ${CTID} -- bash -c "
cat > /etc/systemd/system/n8n.service <<'SERVICE_EOF'
[Unit]
Description=n8n Workflow Automation
After=docker.service postgresql.service
Requires=docker.service postgresql.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/n8n
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
Restart=on-failure
[Install]
WantedBy=multi-user.target
SERVICE_EOF
systemctl daemon-reload
systemctl enable n8n.service
"
log_success "Systemd Service erstellt"
# =====================================================
# Schritt 10: IP-Adresse ermitteln
# =====================================================
log_info "Schritt 10: IP-Adresse ermitteln..."
sleep 5
CONTAINER_IP=$(pct exec ${CTID} -- hostname -I | awk '{print $1}')
log_success "Container IP: ${CONTAINER_IP}"
# =====================================================
# Schritt 11: Credentials-Datei erstellen
# =====================================================
log_info "Schritt 11: Credentials-Datei erstellen..."
CREDENTIALS_FILE="${SCRIPT_DIR}/credentials/botkonzept-lxc-${CTID}.json"
mkdir -p "${SCRIPT_DIR}/credentials"
cat > "${CREDENTIALS_FILE}" <<EOF
{
"lxc": {
"lxc_id": ${CTID},
"hostname": "${HOSTNAME}",
"ip": "${CONTAINER_IP}",
"cores": ${CORES},
"memory": ${MEMORY},
"disk": ${DISK}
},
"n8n": {
"url_internal": "http://${CONTAINER_IP}:5678",
"url_external": "http://${CONTAINER_IP}:5678",
"owner_email": "${N8N_OWNER_EMAIL}",
"owner_password": "${N8N_OWNER_PASSWORD}",
"encryption_key": "${N8N_ENCRYPTION_KEY}",
"webhook_base": "http://${CONTAINER_IP}:5678/webhook"
},
"postgresql": {
"host": "localhost",
"port": 5432,
"database": "botkonzept",
"user": "postgres",
"password": "${PG_PASSWORD}"
},
"workflows": {
"registration": "/opt/n8n/registration-workflow.json",
"trial_management": "/opt/n8n/trial-workflow.json"
},
"frontend": {
"test_url": "http://192.168.0.20:8000",
"webhook_url": "http://${CONTAINER_IP}:5678/webhook/botkonzept-registration"
}
}
EOF
log_success "Credentials gespeichert: ${CREDENTIALS_FILE}"
# =====================================================
# Zusammenfassung
# =====================================================
echo ""
echo "=========================================="
echo " BotKonzept LXC Setup abgeschlossen! ✅"
echo "=========================================="
echo ""
echo "LXC Details:"
echo " CTID: ${CTID}"
echo " Hostname: ${HOSTNAME}"
echo " IP: ${CONTAINER_IP}"
echo ""
echo "n8n:"
echo " URL: http://${CONTAINER_IP}:5678"
echo " E-Mail: ${N8N_OWNER_EMAIL}"
echo " Passwort: ${N8N_OWNER_PASSWORD}"
echo ""
echo "PostgreSQL:"
echo " Host: localhost (im Container)"
echo " Database: botkonzept"
echo " User: postgres"
echo " Passwort: ${PG_PASSWORD}"
echo ""
echo "Nächste Schritte:"
echo " 1. n8n öffnen: http://${CONTAINER_IP}:5678"
echo " 2. Mit obigen Credentials einloggen"
echo " 3. Workflows importieren:"
echo " - /opt/n8n/registration-workflow.json"
echo " - /opt/n8n/trial-workflow.json"
echo " 4. Credentials in n8n erstellen (siehe QUICK_START.md)"
echo " 5. Workflows aktivieren"
echo " 6. Frontend Webhook-URL aktualisieren:"
echo " http://${CONTAINER_IP}:5678/webhook/botkonzept-registration"
echo ""
echo "Credentials-Datei: ${CREDENTIALS_FILE}"
echo "=========================================="