Files
Crumb-Core-v.1/native_crumbcore_v1/native-install.sh
2025-12-24 18:26:59 +01:00

374 lines
9.9 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

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
#
# Crumbforest Native Installation Script
# Installs Crumbforest directly on Linux server without Docker
#
# Requirements:
# - Debian/Ubuntu Linux
# - Python 3.11+
# - MariaDB/MySQL
# - NGINX
# - Qdrant running on localhost:6333
#
# Run as root or with sudo
#
set -e # Exit on error
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration
INSTALL_DIR="/opt/crumbforest"
APP_USER="crumbforest"
APP_GROUP="crumbforest"
LOG_DIR="/var/log/crumbforest"
SYSTEMD_DIR="/etc/systemd/system"
NGINX_SITES="/etc/nginx/sites-available"
NGINX_ENABLED="/etc/nginx/sites-enabled"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
# Functions
print_success() {
echo -e "${GREEN}${NC} $1"
}
print_warning() {
echo -e "${YELLOW}${NC} $1"
}
print_error() {
echo -e "${RED}${NC} $1"
}
print_info() {
echo -e "${BLUE}${NC} $1"
}
check_root() {
if [ "$EUID" -ne 0 ]; then
print_error "Bitte als root ausführen oder sudo verwenden"
exit 1
fi
}
check_command() {
if command -v $1 &> /dev/null; then
print_success "$1 ist installiert"
return 0
else
print_error "$1 ist NICHT installiert"
return 1
fi
}
# Banner
echo "============================================"
echo "🦉 Crumbforest Native Installation"
echo "============================================"
echo ""
print_info "Installation nach: $INSTALL_DIR"
print_info "App User: $APP_USER"
print_info "Logs: $LOG_DIR"
echo ""
# Step 1: Check prerequisites
echo "=== Step 1: Prerequisites Check ==="
echo ""
check_root
all_ok=true
if ! check_command python3; then
print_error "Python 3 ist erforderlich!"
all_ok=false
else
PYTHON_VERSION=$(python3 --version | awk '{print $2}')
print_info "Python Version: $PYTHON_VERSION"
fi
if ! check_command pip3; then
print_error "pip3 ist erforderlich!"
all_ok=false
fi
if ! check_command nginx; then
print_error "NGINX ist erforderlich!"
all_ok=false
fi
if ! check_command mysql || ! check_command mariadb; then
print_warning "MySQL/MariaDB CLI nicht gefunden (Server könnte trotzdem laufen)"
fi
# Check if Qdrant is running
if curl -s http://localhost:6333/collections > /dev/null 2>&1; then
print_success "Qdrant läuft auf localhost:6333"
else
print_warning "Qdrant nicht erreichbar auf localhost:6333 (wird später benötigt)"
fi
if [ "$all_ok" = false ]; then
print_error "Bitte installiere die fehlenden Dependencies"
exit 1
fi
echo ""
# Step 2: Create system user
echo "=== Step 2: System User Setup ==="
echo ""
if id "$APP_USER" &>/dev/null; then
print_warning "User $APP_USER existiert bereits"
else
useradd --system --no-create-home --shell /bin/false "$APP_USER"
print_success "User $APP_USER erstellt"
fi
echo ""
# Step 3: Create directory structure
echo "=== Step 3: Directory Structure ==="
echo ""
print_info "Erstelle Verzeichnisse..."
mkdir -p "$INSTALL_DIR"/{app,docs,logs,venv}
mkdir -p "$LOG_DIR"
print_success "Verzeichnisse erstellt"
# Step 4: Copy application files
echo ""
echo "=== Step 4: Copy Application Files ==="
echo ""
print_info "Kopiere Application Code..."
cp -r "$PROJECT_ROOT/app"/* "$INSTALL_DIR/app/"
print_success "App Code kopiert"
print_info "Kopiere Dokumentation..."
# Check for docs_git (preferred source) or docs
DOCS_SOURCE=""
if [ -d "$PROJECT_ROOT/docs_git" ]; then
DOCS_SOURCE="$PROJECT_ROOT/docs_git"
print_info "Nutze docs_git als Quelle"
elif [ -d "$PROJECT_ROOT/docs" ]; then
DOCS_SOURCE="$PROJECT_ROOT/docs"
print_info "Nutze docs als Quelle"
fi
if [ -n "$DOCS_SOURCE" ]; then
cp -r "$DOCS_SOURCE"/* "$INSTALL_DIR/docs/" || true
# Fix: Create symlink in app/docs so hardcoded paths work (mimics Docker volume)
if [ ! -L "$INSTALL_DIR/app/docs" ]; then
# Remove empty dir if it exists
if [ -d "$INSTALL_DIR/app/docs" ]; then rmdir "$INSTALL_DIR/app/docs" 2>/dev/null || true; fi
ln -sf "$INSTALL_DIR/docs" "$INSTALL_DIR/app/docs"
print_success "Docs Symlink erstellt (app/docs -> ../docs)"
fi
print_success "Docs kopiert von $(basename "$DOCS_SOURCE")"
else
print_warning "Kein Dokumentations-Verzeichnis (docs_git oder docs) gefunden"
fi
print_info "Kopiere Root Dokumentation..."
cp "$PROJECT_ROOT"/*.md "$INSTALL_DIR/docs/" 2>/dev/null || true
print_info "Kopiere Konfiguration..."
if [ -f "$PROJECT_ROOT/crumbforest_config.json" ]; then
cp "$PROJECT_ROOT/crumbforest_config.json" "$INSTALL_DIR/app/"
print_success "Config kopiert"
fi
echo ""
# Step 5: Python virtual environment
echo "=== Step 5: Python Virtual Environment ==="
echo ""
print_info "Erstelle Virtual Environment..."
python3 -m venv "$INSTALL_DIR/venv"
print_success "venv erstellt"
print_info "Installiere Python Dependencies..."
"$INSTALL_DIR/venv/bin/pip" install --upgrade pip
"$INSTALL_DIR/venv/bin/pip" install -r "$PROJECT_ROOT/app/requirements.txt"
print_success "Dependencies installiert"
echo ""
# Step 6: Environment configuration
echo "=== Step 6: Environment Configuration ==="
echo ""
if [ ! -f "$INSTALL_DIR/.env" ]; then
print_info "Erstelle .env aus Template..."
cp "$SCRIPT_DIR/env.production.template" "$INSTALL_DIR/.env"
# Generate random secrets
APP_SECRET=$(openssl rand -hex 32)
SECRET_KEY=$(openssl rand -hex 32)
DB_PASSWORD=$(openssl rand -base64 24 | tr -d "=+/" | cut -c1-20)
# Replace placeholders
sed -i "s/CHANGE_ME_TO_RANDOM_64_CHAR_STRING/$APP_SECRET/g" "$INSTALL_DIR/.env"
sed -i "s/CHANGE_ME_TO_SECURE_PASSWORD/$DB_PASSWORD/g" "$INSTALL_DIR/.env"
print_success ".env erstellt"
print_warning "WICHTIG: Bitte API Keys in $INSTALL_DIR/.env eintragen!"
else
print_warning ".env existiert bereits - wird nicht überschrieben"
fi
echo ""
# Step 7: Set permissions
echo "=== Step 7: Permissions ==="
echo ""
print_info "Setze Besitzer und Rechte..."
chown -R "$APP_USER:$APP_GROUP" "$INSTALL_DIR"
chown -R "$APP_USER:$APP_GROUP" "$LOG_DIR"
chmod 750 "$INSTALL_DIR"
chmod 750 "$INSTALL_DIR/app"
chmod 600 "$INSTALL_DIR/.env" # Sensitive data!
chmod -R 755 "$INSTALL_DIR/app/static" 2>/dev/null || true
# Fix: Symlink .env to app directory for Pydantic Settings
if [ ! -L "$INSTALL_DIR/app/.env" ]; then
print_info "Erstelle Symlink für .env in App-Verzeichnis..."
ln -sf "$INSTALL_DIR/.env" "$INSTALL_DIR/app/.env"
fi
chown -h $APP_USER:$APP_GROUP "$INSTALL_DIR/app/.env"
print_success "Permissions gesetzt"
echo ""
# Step 8: Install systemd services
echo "=== Step 8: systemd Services ==="
echo ""
print_info "Installiere systemd Service Files..."
cp "$SCRIPT_DIR/systemd/crumbforest.service" "$SYSTEMD_DIR/"
cp "$SCRIPT_DIR/systemd/crumbforest-indexing.service" "$SYSTEMD_DIR/"
print_success "Service Files kopiert"
print_info "Aktiviere Services..."
systemctl daemon-reload
systemctl enable crumbforest.service
systemctl enable crumbforest-indexing.service
print_success "Services aktiviert"
echo ""
# Step 9: Install NGINX configuration
echo "=== Step 9: NGINX Configuration ==="
echo ""
print_info "Installiere NGINX Config..."
cp "$SCRIPT_DIR/nginx/crumbforest.nginx.conf" "$NGINX_SITES/crumbforest"
cp "$SCRIPT_DIR/nginx/crumbforest-locations.conf" "$NGINX_SITES/"
print_success "NGINX Config installiert"
# Enable site
if [ ! -L "$NGINX_ENABLED/crumbforest" ]; then
ln -s "$NGINX_SITES/crumbforest" "$NGINX_ENABLED/crumbforest"
print_success "NGINX Site aktiviert"
else
print_warning "NGINX Site bereits aktiviert"
fi
# Test NGINX config
if nginx -t > /dev/null 2>&1; then
print_success "NGINX Config Test OK"
else
print_error "NGINX Config Test FAILED - bitte prüfen!"
fi
echo ""
# Step 10: Install Crumb Doktor (Global Tool)
echo "=== Step 10: Install Crumb Doktor ==="
echo ""
DOKTOR_SRC="$PROJECT_ROOT/crumbpages-doktor.sh"
DOKTOR_DEST="/usr/local/bin/crumb-doktor"
if [ -f "$DOKTOR_SRC" ]; then
print_info "Installiere crumbpages-doktor.sh als globalen Befehl..."
cp "$DOKTOR_SRC" "$DOKTOR_DEST"
chmod +x "$DOKTOR_DEST"
print_success "Installiert als: $DOKTOR_DEST"
print_info "Du kannst jetzt überall 'crumb-doktor' verwenden!"
else
print_warning "crumbpages-doktor.sh nicht gefunden im Repo-Root"
fi
echo ""
# Step 11: Database setup reminder
echo "=== Step 11: Database Setup ==="
echo ""
print_warning "Datenbank muss manuell eingerichtet werden!"
echo ""
echo "Bitte folgende SQL-Befehle ausführen:"
echo ""
echo " mysql -u root -p"
echo " CREATE DATABASE IF NOT EXISTS crumbforest CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
echo " CREATE USER IF NOT EXISTS 'crumb_prod'@'localhost' IDENTIFIED BY 'YOUR_PASSWORD';"
echo " GRANT ALL PRIVILEGES ON crumbforest.* TO 'crumb_prod'@'localhost';"
echo " FLUSH PRIVILEGES;"
echo ""
echo "Dann Datenbank-Schema importieren:"
echo " mysql -u crumb_prod -p crumbforest < $PROJECT_ROOT/compose/init/01_schema.sql"
echo ""
read -p "Drücke ENTER wenn Datenbank eingerichtet ist..."
echo ""
# Summary
echo "============================================"
echo "✓ Installation abgeschlossen!"
echo "============================================"
echo ""
echo "Nächste Schritte:"
echo ""
echo "1. API Keys eintragen:"
echo " sudo nano $INSTALL_DIR/.env"
echo ""
echo "2. Services starten:"
echo " sudo systemctl start crumbforest-indexing # Einmalig"
echo " sudo systemctl start crumbforest"
echo ""
echo "3. NGINX neu laden:"
echo " sudo systemctl reload nginx"
echo ""
echo "4. Status prüfen:"
echo " sudo systemctl status crumbforest"
echo " sudo journalctl -u crumbforest -f"
echo ""
echo "5. Health Check:"
echo " curl http://localhost:8000/health"
echo ""
echo "URLs:"
echo " - App: http://crumbforest.194-164-194-191.sslip.io"
echo " - IP: http://194.164.194.191"
echo ""
echo "Installation Location: $INSTALL_DIR"
echo "Logs: $LOG_DIR"
echo "systemd Logs: journalctl -u crumbforest"
echo ""
echo "Wuuuuhuuu! 🦉💚"
echo ""