#!/bin/bash # ========================================== # WKVS Full Stack Installation Script # Autor: Euria # Datum: 2026-04-20 # ========================================== set -e # Stoppt das Skript bei jedem Fehler export DEBIAN_FRONTEND=noninteractive echo "" echo "" echo "==========================================" echo " WKVS Full Stack Installation" echo "==========================================" echo "" echo "" read -p "Dieses Skript funktioniert nur auf einer leeren Linux Instalation. Fohrtfahren? [y/n/c]: " choiceInstall case $choiceInstall in [yY]*) ;; [nN]*) echo "Installation abgebrochen." exit 0 ;; [cC]*) echo "Installation abgebrochen." exit 0 ;; *) echo "Ungültige Eingabe." exit 1 ;; esac # --- 1. System Update & Basisinstallation --- echo "Schritt 1: System aktualisieren und Basis-Pakete installieren..." sudo apt update sudo apt install -y mariadb-server apache2 nginx curl dig certbot python3-certbot-nginx # --- 2. MariaDB Installation & Konfiguration --- echo "Schritt 2: MariaDB Konfiguration..." read -p "Willst du die Installation komplett automatisch abschließen? [y/n/c]: " choice case $choice in [yY]*) PREFIX=$(openssl rand -hex 3) DB_NAME="${PREFIX}_wkvs_db" DB_USER_NORMAL="${PREFIX}_wkvs_user" DB_USER_GUEST="${PREFIX}_wkvs_guest" DB_PASS_NORMAL=$(openssl rand -base64 24) DB_PASS_GUEST=$(openssl rand -base64 24) DB_PORT="3306" AUTO_INSTALL="true" ;; [nN]*) read -p "Name der Datenbank: " DB_NAME read -sp "Passwort für $DB_USER_NORMAL: " DB_PASS_NORMAL echo "" read -p "Name des Gastbenutzers: " DB_USER_GUEST read -sp "Passwort für $DB_USER_GUEST: " DB_PASS_GUEST echo "" read -p "Custom Port (Standard 3306): " DB_PORT DB_PORT=${DB_PORT:-3306} AUTO_INSTALL="false" ;; [cC]*) echo "Installation abgebrochen." exit 0 ;; *) echo "Ungültige Eingabe." exit 1 ;; esac # MariaDB Port umstellen (falls Custom) if [ "$DB_PORT" != "3306" ]; then echo " Stelle MariaDB auf Port $DB_PORT um..." if [ -f /etc/mysql/mariadb.conf.d/50-server.cnf ]; then sudo sed -i "s/.*port\s*=\s*3306/port = $DB_PORT/" /etc/mysql/mariadb.conf.d/50-server.cnf sudo systemctl restart mariadb else echo " Fehler: Konfigurationsdatei nicht gefunden." exit 1 fi else sudo systemctl restart mariadb fi # --- 3. Datenbank Setup --- echo "Schritt 3: Datenbank und Benutzer erstellen..." sudo mysql -P "$DB_PORT" < config/.env.db DB_USER=$DB_USER_NORMAL DB_PASSWORD=$DB_PASS_NORMAL DB_NAME=$DB_NAME DB_HOST=127.0.0.1 DB_PORT=$DB_PORT EOT cat < config/.env.db-guest DB_GUEST_USER=$DB_USER_GUEST DB_GUEST_PASSWORD=$DB_PASS_GUEST DB_NAME=$DB_NAME DB_HOST=127.0.0.1 DB_PORT=$DB_PORT EOT # SQL Import (falls vorhanden) if [ -f "setup/database/generate-sql.php" ]; then echo " Generiere SQL-Struktur..." php setup/database/generate-sql.php fi if [ -f "setup/database/sql-database.sql" ]; then echo " Importiere Datenbank-Struktur..." sudo mysql -P "$DB_PORT" "$DB_NAME" < setup/database/sql-database.sql echo " Datenbank-Schema erfolgreich importiert." else echo " Warnung: SQL-Datei nicht gefunden. Import übersprungen." fi # --- 5. Verschlüsselungsschlüssel --- if [ "$AUTO_INSTALL" = "true" ]; then ENCRYPTION_KEY=$(openssl rand -base64 32) echo " Automatischer Modus: Verschlüsselungsschlüssel generiert." else read -sp "Schlüssel zur symmetrischen Verschlüsselung (durch WK-Leitung): " ENCRYPTION_KEY echo "" fi cat < config/.env.pw-encryption-key PW_ENCRYPTION_KEY=$ENCRYPTION_KEY EOT # --- 6. Composer & PHP Dependencies --- if ! command -v composer &> /dev/null; then echo " Composer wird installiert..." sudo apt install -y composer fi echo " Installiere Composer Pakete..." composer require vlucas/phpdotenv composer require phpmailer/phpmailer composer require shuchkin/simplexlsx composer require sprain/swiss-qr-bill composer require james-heinrich/getid3 composer require chriskonnertz/string-calc composer require tecnickcom/tcpdf # --- 7. Node.js WebSocket --- cd websocket || { echo "Fehler: websocket Ordner nicht gefunden!"; exit 1; } npm init -y npm install redis ws dotenv npm install -g pm2 cd .. echo " WebSocket (Node.js) Installation abgeschlossen." # --- 8. Apache & Nginx Konfiguration --- echo "Schritt 8: Webserver konfigurieren..." # Apache auf internen Port umstellen APACHE_INTERNAL_PORT=8080 if grep -q "Listen 80" /etc/apache2/ports.conf 2>/dev/null; then sudo sed -i "s/^Listen 80$/Listen $APACHE_INTERNAL_PORT/" /etc/apache2/ports.conf # Falls Default VHost auch 80 hat if [ -f /etc/apache2/sites-enabled/000-default.conf ]; then sudo sed -i "s/Listen 80/Listen $APACHE_INTERNAL_PORT/" /etc/apache2/sites-enabled/000-default.conf 2>/dev/null || true fi fi sudo systemctl restart apache2 echo " Apache auf internen Port $APACHE_INTERNAL_PORT umgestellt." # --- 9. Nginx Reverse Proxy & SSL --- echo "Schritt 9: Nginx Reverse Proxy & HTTPS einrichten..." read -p "Domain der Webseite: (Beispiel: wk.wkvs.ch) " DOMAIN if [ -z "$DOMAIN" ]; then echo "❌ FEHLER: Die Domain darf nicht leer sein!" exit 1 fi DOMAIN=$(echo "$DOMAIN" | xargs) # DNS Prüfung echo " DNS-Prüfung für $DOMAIN..." RESOLVED_IP=$(dig +short $DOMAIN 2>/dev/null | head -n1) SERVER_IP=$(curl -s https://api.ipify.org 2>/dev/null) if [ -z "$RESOLVED_IP" ]; then echo "❌ FEHLER: Domain '$DOMAIN' kann nicht aufgelöst werden." echo " Bitte warten Sie, bis die DNS-Einträge aktiv sind." exit 1 fi if [ -n "$SERVER_IP" ] && [ "$RESOLVED_IP" != "$SERVER_IP" ]; then echo "⚠️ WARNUNG: Domain zeigt auf $RESOLVED_IP, Server ist $SERVER_IP." echo " Bitte prüfen Sie Ihre DNS-Einträge." read -p "Möchten Sie trotzdem fortfahren? [y/n]: " confirm if [ "$confirm" != "y" ]; then exit 0 fi fi # Nginx Konfiguration erstellen NGINX_CONF="/etc/nginx/sites-available/$DOMAIN" NGINX_LINK="/etc/nginx/sites-enabled/$DOMAIN" rm -f /etc/nginx/sites-enabled/default 2>/dev/null || true rm -f "$NGINX_CONF" 2>/dev/null || true cat > "$NGINX_CONF" < HTTPS Weiterleitung server { listen 80; server_name $DOMAIN; return 301 https://\$host\$request_uri; } # HTTPS Server server { listen 443 ssl http2; server_name $DOMAIN; ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; # WebSocket Route location /ws/ { proxy_pass http://127.0.0.1:8082; proxy_http_version 1.1; proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \$scheme; proxy_read_timeout 3600s; proxy_send_timeout 3600s; proxy_connect_timeout 75s; } # Versteckte Dateien location ~ /\. { deny all; access_log off; log_not_found off; } # Apache Proxy location / { proxy_pass http://127.0.0.1:$APACHE_INTERNAL_PORT; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \$scheme; } } EOF sudo ln -sf "$NGINX_CONF" "$NGINX_LINK" # Let's Encrypt Zertifikat echo " Starte Let's Encrypt Zertifikatsanfrage..." read -p "E-Mail für Let's Encrypt: " EMAIL sudo certbot --nginx -d $DOMAIN --agree-tos --no-eff-email --redirect --email "$EMAIL" --non-interactive # Dienste neu starten sudo systemctl reload nginx sudo systemctl restart apache2 echo "==========================================" echo "✅ Installation erfolgreich abgeschlossen!" echo "==========================================" echo "Zusammenfassung:" echo "- Datenbank: $DB_NAME (Port: $DB_PORT)" echo "- Apache intern: Port $APACHE_INTERNAL_PORT" echo "- Node.js WS: Port 8082 (unter /ws/)" echo "- HTTPS: https://$DOMAIN/intern/wk-leitung/logindata" echo "" echo "Nächste Schritte:" echo "1. Starten Sie den WebSocket Server: cd websocket && pm2 start app.js" echo "2. Testen Sie die Seite: https://$DOMAIN/intern/wk-leitung/logindata"