#!/bin/bash # RZ Deployment Script für Crumbcore v1 # Sicher, idempotent, mit Rollback-Option set -e # Exit on error # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Config COMPOSE_FILE="rz-deployment.yml" ENV_FILE=".env.rz" BACKUP_DIR="./backups/$(date +%Y%m%d_%H%M%S)" echo -e "${BLUE}🌲 Crumbcore RZ Deployment${NC}" echo "==================================" echo "" # 1. Pre-flight Checks echo -e "${YELLOW}[1/7] Pre-flight Checks...${NC}" # Check if running in RZ if [ ! -f "/etc/rz-marker" ]; then echo -e "${YELLOW}⚠️ Warnung: Nicht im RZ erkannt. Fortfahren? (y/n)${NC}" read -r response if [ "$response" != "y" ]; then exit 0 fi fi # Check Docker if ! command -v docker &> /dev/null; then echo -e "${RED}❌ Docker nicht gefunden!${NC}" exit 1 fi echo -e "${GREEN}✅ Docker verfügbar${NC}" # Check Docker Compose if ! docker compose version &> /dev/null; then echo -e "${RED}❌ Docker Compose nicht gefunden!${NC}" exit 1 fi echo -e "${GREEN}✅ Docker Compose verfügbar${NC}" # Check ENV File if [ ! -f "$ENV_FILE" ]; then echo -e "${YELLOW}⚠️ $ENV_FILE nicht gefunden. Erstelle Template...${NC}" cat > "$ENV_FILE" << 'EOF' # RZ Crumbcore Environment Variables # WICHTIG: Alle Secrets hier eintragen! # Database Passwords DB_PASSWORD=CHANGE_ME_$(openssl rand -hex 16) DB_ROOT_PASSWORD=CHANGE_ME_$(openssl rand -hex 24) # Application Secret SECRET_KEY=CHANGE_ME_$(openssl rand -hex 32) # OpenRouter API Key OPENROUTER_API_KEY=sk-or-v1-... # Optional: Einzelne Provider # OPENAI_API_KEY=sk-... # ANTHROPIC_API_KEY=sk-ant-... EOF echo -e "${RED}❌ Bitte $ENV_FILE ausfüllen und erneut starten!${NC}" exit 1 fi # Validate ENV File if grep -q "CHANGE_ME" "$ENV_FILE"; then echo -e "${RED}❌ $ENV_FILE enthält noch CHANGE_ME Platzhalter!${NC}" exit 1 fi echo -e "${GREEN}✅ ENV File validiert${NC}" # 2. Backup existing data if [ -d "backups" ]; then echo -e "${YELLOW}[2/7] Erstelle Backup...${NC}" mkdir -p "$BACKUP_DIR" # Backup Volumes if docker volume ls | grep -q "rz-crumbcore-db-data"; then docker run --rm -v rz-crumbcore-db-data:/data -v "$BACKUP_DIR":/backup \ alpine tar czf /backup/db-data.tar.gz -C /data . echo -e "${GREEN}✅ DB Backup erstellt${NC}" fi if docker volume ls | grep -q "rz-crumbcore-qdrant-data"; then docker run --rm -v rz-crumbcore-qdrant-data:/data -v "$BACKUP_DIR":/backup \ alpine tar czf /backup/qdrant-data.tar.gz -C /data . echo -e "${GREEN}✅ Qdrant Backup erstellt${NC}" fi else echo -e "${YELLOW}[2/7] Überspringe Backup (erste Installation)${NC}" fi # 3. Pull latest images echo -e "${YELLOW}[3/7] Ziehe Docker Images...${NC}" docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" pull echo -e "${GREEN}✅ Images aktualisiert${NC}" # 4. Stop old containers (if running) if docker ps | grep -q "rz-crumbcore"; then echo -e "${YELLOW}[4/7] Stoppe alte Container...${NC}" docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" down echo -e "${GREEN}✅ Container gestoppt${NC}" else echo -e "${YELLOW}[4/7] Keine alten Container gefunden${NC}" fi # 5. Start services echo -e "${YELLOW}[5/7] Starte Services...${NC}" docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" up -d # Wait for services echo "Warte auf Services..." sleep 10 # 6. Health Checks echo -e "${YELLOW}[6/7] Health Checks...${NC}" # Check DB if docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" exec -T db \ sh -c 'mariadb -u$MARIADB_USER -p$MARIADB_PASSWORD $MARIADB_DATABASE -e "SELECT 1"' &> /dev/null; then echo -e "${GREEN}✅ Database erreichbar${NC}" else echo -e "${RED}❌ Database Check fehlgeschlagen!${NC}" echo "Logs:" docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" logs db exit 1 fi # Check Qdrant if curl -sf http://localhost:6333/health &> /dev/null; then echo -e "${GREEN}✅ Qdrant erreichbar${NC}" else echo -e "${RED}❌ Qdrant Check fehlgeschlagen!${NC}" exit 1 fi # Check App max_retries=30 retry=0 while [ $retry -lt $max_retries ]; do if curl -sf http://localhost:8000/health &> /dev/null; then echo -e "${GREEN}✅ Application erreichbar${NC}" break fi retry=$((retry + 1)) echo "Warte auf App... ($retry/$max_retries)" sleep 2 done if [ $retry -eq $max_retries ]; then echo -e "${RED}❌ Application nicht erreichbar nach ${max_retries} Versuchen!${NC}" echo "Logs:" docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" logs app exit 1 fi # 7. Post-Deployment echo -e "${YELLOW}[7/7] Post-Deployment Checks...${NC}" # Check Collections collections=$(curl -s http://localhost:6333/collections | jq -r '.result.collections[].name' 2>/dev/null || echo "") if [ -n "$collections" ]; then echo -e "${GREEN}✅ Qdrant Collections:${NC}" echo "$collections" | sed 's/^/ - /' else echo -e "${YELLOW}⚠️ Keine Collections gefunden (werden beim ersten Index erstellt)${NC}" fi # Show URLs echo "" echo -e "${GREEN}==================================" echo "🎉 Deployment erfolgreich!" echo "==================================${NC}" echo "" echo -e "${BLUE}Services:${NC}" echo " - Application: http://localhost:8000" echo " - API Docs: http://localhost:8000/docs" echo " - Qdrant UI: http://localhost:6333/dashboard" echo "" echo -e "${BLUE}Admin Login:${NC}" echo " - URL: http://localhost:8000/de/login" echo " - Email: admin@crumb.local" echo " - Password: admin123" echo "" echo -e "${BLUE}Logs anzeigen:${NC}" echo " docker compose -f $COMPOSE_FILE logs -f app" echo "" echo -e "${BLUE}Stoppen:${NC}" echo " docker compose -f $COMPOSE_FILE down" echo "" # Optional: Auto-Index Docs echo -e "${YELLOW}Möchten Sie jetzt Dokumente indexieren? (y/n)${NC}" read -r response if [ "$response" = "y" ]; then echo "Indexiere Dokumente..." docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" exec app \ python3 -c "from scripts.index_docs import index_documents; \ index_documents('docs/rz-nullfeld', 'docs_rz_nullfeld_'); \ index_documents('docs/crumbforest', 'docs_crumbforest_'); \ print('✅ Indexing abgeschlossen!')" fi echo "" echo -e "${GREEN}🌲 Bereit für's RZ! Viel Erfolg!${NC}"