#!/bin/bash # =================================================================== # Raspberry Pi Vollautomatische Installation - MYP Druckerverwaltung # Für Debian 12 (Bookworm) auf Raspberry Pi # Nach offizieller Raspberry Pi Kiosk-Anleitung optimiert # =================================================================== set -e # Beende bei Fehlern # 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 # Logging-Funktion log() { echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] $1${NC}" } error() { echo -e "${RED}[FEHLER] $1${NC}" exit 1 } warning() { echo -e "${YELLOW}[WARNUNG] $1${NC}" } info() { echo -e "${BLUE}[INFO] $1${NC}" } # Prüfe ob als Root ausgeführt if [ "$EUID" -ne 0 ]; then error "Dieses Skript muss als Root ausgeführt werden. Verwende: sudo $0" fi log "=== MYP Druckerverwaltung - Raspberry Pi Installation ===" log "Debian 12 (Bookworm) Kiosk-Modus nach offizieller Anleitung" echo # Konfigurationsvariablen APP_USER="myp" KIOSK_USER="kiosk" APP_DIR="/opt/myp-druckerverwaltung" BACKUP_DIR="/opt/myp-backups" SERVICE_NAME="myp-druckerverwaltung" KIOSK_SERVICE_NAME="myp-kiosk" KIOSK_URL="http://localhost" CURRENT_DIR="$(pwd)" # System-Pfade SYSTEMD_DIR="/etc/systemd/system" NGINX_SITES_AVAILABLE="/etc/nginx/sites-available" NGINX_SITES_ENABLED="/etc/nginx/sites-enabled" LIGHTDM_CONF="/etc/lightdm/lightdm.conf" LOCAL_BIN="/usr/local/bin" CRON_DIR="/etc/cron.d" KIOSK_HOME="/home/$KIOSK_USER" PI_HOME="/home/pi" # Bereinige unbenötigte Pakete (entsprechend offizieller Anleitung) log "Entferne unbenötigte Pakete zur Speicheroptimierung..." export DEBIAN_FRONTEND=noninteractive apt-get purge -y wolfram-engine scratch scratch2 nuscratch sonic-pi idle3 smartsim java-common minecraft-pi libreoffice* || true apt-get autoremove -y apt-get clean # Systemupdate log "Aktualisiere Paketlisten und System..." apt-get update -y apt-get upgrade -y --allow-downgrades --allow-remove-essential --allow-change-held-packages # Installiere erforderliche Pakete (nach offizieller Anleitung) log "Installiere Systempakete für Kiosk-Modus..." apt-get install -y \ python3 \ python3-pip \ python3-venv \ python3-dev \ git \ curl \ wget \ unzip \ sqlite3 \ nginx \ supervisor \ chromium-browser \ xorg \ openbox \ lightdm \ x11-xserver-utils \ xdotool \ unclutter \ sed \ build-essential \ libssl-dev \ libffi-dev \ libjpeg-dev \ zlib1g-dev \ nodejs \ npm \ --no-install-recommends || true # Erstelle Anwendungsbenutzer log "Erstelle Anwendungsbenutzer '$APP_USER'..." if ! id "$APP_USER" &>/dev/null; then useradd -m -s /bin/bash "$APP_USER" usermod -aG sudo "$APP_USER" log "Benutzer '$APP_USER' erstellt" else log "Benutzer '$APP_USER' existiert bereits" fi # Erstelle Kiosk-Benutzer (nach offizieller Anleitung) log "Erstelle Kiosk-Benutzer '$KIOSK_USER'..." if ! id "$KIOSK_USER" &>/dev/null; then useradd -m -s /bin/bash "$KIOSK_USER" usermod -aG audio,video "$KIOSK_USER" log "Benutzer '$KIOSK_USER' erstellt" else log "Benutzer '$KIOSK_USER' existiert bereits" fi # Erstelle Anwendungsverzeichnis log "Erstelle Anwendungsverzeichnis..." mkdir -p "$APP_DIR" chown "$APP_USER:$APP_USER" "$APP_DIR" # Kopiere Anwendung if [ ! -d "$APP_DIR/.git" ]; then log "Kopiere Anwendung..." if [ -f "app.py" ]; then log "Kopiere lokale Anwendung..." cp -r "$CURRENT_DIR"/* "$APP_DIR/" chown -R "$APP_USER:$APP_USER" "$APP_DIR" else error "Anwendungsdateien nicht gefunden. Führe das Skript im Anwendungsverzeichnis aus." fi else log "Anwendung bereits vorhanden, aktualisiere..." cd "$APP_DIR" sudo -u "$APP_USER" git pull || log "Git pull nicht möglich - lokale Installation" fi cd "$APP_DIR" # Python Virtual Environment erstellen log "Erstelle Python Virtual Environment..." sudo -u "$APP_USER" python3 -m venv venv sudo -u "$APP_USER" ./venv/bin/pip install --upgrade pip # Installiere Python-Abhängigkeiten log "Installiere Python-Abhängigkeiten..." if [ -f "$CURRENT_DIR/requirements.txt" ]; then # Erstelle korrigierte requirements.txt ohne Verweis auf andere Datei cat > "$APP_DIR/requirements_fixed.txt" << 'EOF' # MYP Platform - Python Dependencies Flask==3.0.0 Flask-Login==0.6.3 Flask-WTF==1.2.1 Flask-Limiter==3.5.0 SQLAlchemy==2.0.41 PyP100 Werkzeug==3.0.1 bcrypt==4.1.2 redis==5.0.1 cryptography==42.0.8 pytest==7.4.3 pytest-cov==4.1.0 gunicorn==21.2.0 psutil==5.9.6 requests==2.31.0 Jinja2==3.1.2 MarkupSafe==2.1.3 itsdangerous==2.1.2 EOF sudo -u "$APP_USER" ./venv/bin/pip install -r requirements_fixed.txt else # Fallback: Installiere grundlegende Pakete sudo -u "$APP_USER" ./venv/bin/pip install \ flask \ flask-login \ flask-wtf \ flask-limiter \ sqlalchemy \ werkzeug \ requests \ gunicorn fi # Node.js Abhängigkeiten installieren if [ -f "$CURRENT_DIR/package.json" ]; then log "Installiere Node.js Abhängigkeiten..." sudo -u "$APP_USER" npm install # Baue Frontend-Assets falls Tailwind vorhanden if [ -f "$CURRENT_DIR/tailwind.config.js" ]; then log "Baue Frontend-Assets mit Tailwind CSS..." sudo -u "$APP_USER" npm run build:css || true fi fi # Datenbank initialisieren log "Initialisiere Datenbank..." if [ -f "$CURRENT_DIR/models.py" ]; then # Erstelle einfaches DB-Init-Skript cat > "$APP_DIR/init_simple_db.py" << 'EOF' from app import app, db with app.app_context(): db.create_all() print("Datenbank wurde initialisiert") EOF sudo -u "$APP_USER" ./venv/bin/python init_simple_db.py || true rm -f "$APP_DIR/init_simple_db.py" else sudo -u "$APP_USER" touch database.db fi # Erstelle Konfigurationsdatei log "Erstelle Anwendungskonfiguration..." cat > "$APP_DIR/.env" << EOF # MYP Druckerverwaltung Konfiguration FLASK_ENV=production SECRET_KEY=$(openssl rand -hex 32) DATABASE_URL=sqlite:///database.db HOST=0.0.0.0 PORT=5000 DEBUG=False # Kiosk-Modus KIOSK_MODE=true AUTO_LOGIN=true EOF chown "$APP_USER:$APP_USER" "$APP_DIR/.env" # Erstelle Kiosk-Skript (nach offizieller Anleitung) log "Erstelle Kiosk-Skript..." cat > "$KIOSK_HOME/kiosk.sh" << EOF #!/bin/bash # Warte auf System-Bereitschaft sleep 5 # Setze Display-Umgebung export DISPLAY=:0 # Deaktiviere Bildschirmschoner (nach offizieller Anleitung) xset s noblank xset s off xset -dpms # Verstecke Mauszeiger unclutter -idle 0.5 -root & # Bereinige Chromium-Präferenzen (verhindert Crash-Warnungen) sed -i 's/"exited_cleanly":false/"exited_cleanly":true/' $KIOSK_HOME/.config/chromium/Default/Preferences 2>/dev/null || true sed -i 's/"exit_type":"Crashed"/"exit_type":"Normal"/' $KIOSK_HOME/.config/chromium/Default/Preferences 2>/dev/null || true # Warte auf Netzwerk und Anwendung while ! curl -s http://localhost > /dev/null; do echo "Warte auf Anwendung..." sleep 2 done # Starte Chromium im Kiosk-Modus (nach offizieller Anleitung) /usr/bin/chromium-browser \\ --noerrdialogs \\ --disable-infobars \\ --kiosk \\ --no-sandbox \\ --disable-web-security \\ --disable-features=TranslateUI \\ --disable-ipc-flooding-protection \\ --disable-renderer-backgrounding \\ --disable-backgrounding-occluded-windows \\ --disable-background-timer-throttling \\ --disable-background-networking \\ --disable-breakpad \\ --disable-component-extensions-with-background-pages \\ --disable-dev-shm-usage \\ --disable-extensions \\ --disable-features=TranslateUI,BlinkGenPropertyTrees \\ --disable-hang-monitor \\ --disable-popup-blocking \\ --disable-prompt-on-repost \\ --disable-sync \\ --disable-translate \\ --force-color-profile=srgb \\ --no-first-run \\ --autoplay-policy=no-user-gesture-required \\ --start-fullscreen \\ $KIOSK_URL & # Optional: Automatische Tab-Rotation (auskommentiert) # while true; do # sleep 30 # xdotool keydown ctrl+r; xdotool keyup ctrl+r; # Seite neu laden # done EOF chmod +x "$KIOSK_HOME/kiosk.sh" chown "$KIOSK_USER:$KIOSK_USER" "$KIOSK_HOME/kiosk.sh" # Konfiguriere LightDM für automatischen Login (nach offizieller Anleitung) log "Konfiguriere automatischen Login..." cat > "$LIGHTDM_CONF" << EOF [Seat:*] autologin-user=$KIOSK_USER autologin-user-timeout=0 user-session=openbox xserver-command=X -s 0 -dpms EOF # Erstelle Openbox-Konfiguration für Kiosk-Benutzer log "Konfiguriere Openbox für Kiosk-Modus..." mkdir -p "$KIOSK_HOME/.config/openbox" cat > "$KIOSK_HOME/.config/openbox/autostart" << EOF # Starte Kiosk-Anwendung automatisch $KIOSK_HOME/kiosk.sh & EOF chown -R "$KIOSK_USER:$KIOSK_USER" "$KIOSK_HOME/.config" # Erstelle Systemd-Service für die Anwendung log "Erstelle Systemd-Service für Anwendung..." cat > "$SYSTEMD_DIR/$SERVICE_NAME.service" << EOF [Unit] Description=MYP Druckerverwaltung Flask Application After=network.target [Service] Type=simple User=$APP_USER Group=$APP_USER WorkingDirectory=$APP_DIR Environment=PATH=$APP_DIR/venv/bin ExecStart=$APP_DIR/venv/bin/python app.py Restart=always RestartSec=10 StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target EOF # Erstelle Systemd-Service für Kiosk (nach offizieller Anleitung) log "Erstelle Systemd-Service für Kiosk..." cat > "$SYSTEMD_DIR/$KIOSK_SERVICE_NAME.service" << EOF [Unit] Description=MYP Chromium Kiosk Wants=graphical.target After=graphical.target $SERVICE_NAME.service [Service] Environment=DISPLAY=:0.0 Environment=XAUTHORITY=$KIOSK_HOME/.Xauthority Type=simple ExecStart=/bin/bash $KIOSK_HOME/kiosk.sh Restart=on-abort User=$KIOSK_USER Group=$KIOSK_USER [Install] WantedBy=graphical.target EOF # Nginx-Konfiguration log "Konfiguriere Nginx..." cat > "$NGINX_SITES_AVAILABLE/myp-druckerverwaltung" << EOF server { listen 80 default_server; listen [::]:80 default_server; server_name _; location / { proxy_pass http://127.0.0.1:5000; 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; # WebSocket-Support proxy_http_version 1.1; proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection "upgrade"; } # Statische Dateien direkt servieren location /static/ { alias $APP_DIR/static/; expires 1y; add_header Cache-Control "public, immutable"; } } EOF # Aktiviere Nginx-Site rm -f $NGINX_SITES_ENABLED/default ln -sf $NGINX_SITES_AVAILABLE/myp-druckerverwaltung $NGINX_SITES_ENABLED/ # Erstelle Wartungsskript log "Erstelle Wartungsskript..." cat > "$LOCAL_BIN/myp-maintenance" << 'EOF' #!/bin/bash # MYP Druckerverwaltung Wartungsskript case "$1" in start) echo "Starte MYP Druckerverwaltung..." systemctl start myp-druckerverwaltung systemctl start nginx systemctl start myp-kiosk ;; stop) echo "Stoppe MYP Druckerverwaltung..." systemctl stop myp-kiosk systemctl stop myp-druckerverwaltung systemctl stop nginx ;; restart) echo "Starte MYP Druckerverwaltung neu..." systemctl restart myp-druckerverwaltung systemctl restart nginx systemctl restart myp-kiosk ;; status) echo "=== MYP Druckerverwaltung Status ===" systemctl status myp-druckerverwaltung --no-pager echo echo "=== Nginx Status ===" systemctl status nginx --no-pager echo echo "=== Kiosk Status ===" systemctl status myp-kiosk --no-pager ;; logs) echo "=== Anwendungslogs ===" journalctl -u myp-druckerverwaltung -f ;; kiosk-logs) echo "=== Kiosk-Logs ===" journalctl -u myp-kiosk -f ;; update) echo "Aktualisiere MYP Druckerverwaltung..." cd $APP_DIR sudo -u myp git pull || echo "Git pull nicht möglich - lokale Installation" # Aktualisiere Python-Dependencies if [ -f "requirements_fixed.txt" ]; then sudo -u myp ./venv/bin/pip install -r requirements_fixed.txt fi # Aktualisiere Node.js Dependencies falls vorhanden if [ -f "package.json" ]; then sudo -u myp npm install if [ -f "tailwind.config.js" ]; then sudo -u myp npm run build:css || true fi fi systemctl restart myp-druckerverwaltung ;; kiosk-restart) echo "Starte nur Kiosk neu..." systemctl restart myp-kiosk ;; *) echo "Verwendung: $0 {start|stop|restart|status|logs|kiosk-logs|update|kiosk-restart}" exit 1 ;; esac EOF chmod +x $LOCAL_BIN/myp-maintenance # Erstelle Backup-Skript log "Erstelle Backup-Skript..." cat > "$LOCAL_BIN/myp-backup" << EOF #!/bin/bash BACKUP_DIR="$BACKUP_DIR" DATE=\$(date +%Y%m%d_%H%M%S) APP_DIR="$APP_DIR" mkdir -p "\$BACKUP_DIR" echo "Erstelle Backup: \$DATE" # Stoppe Anwendung systemctl stop myp-druckerverwaltung # Erstelle Backup tar -czf "\$BACKUP_DIR/myp_backup_\$DATE.tar.gz" \\ -C "\$APP_DIR" \\ --exclude='node_modules' \\ --exclude='__pycache__' \\ --exclude='venv' \\ database.db \\ .env \\ uploads/ \\ logs/ \\ config/ \\ 2>/dev/null || true # Starte Anwendung systemctl start myp-druckerverwaltung echo "Backup erstellt: \$BACKUP_DIR/myp_backup_\$DATE.tar.gz" # Lösche alte Backups (älter als 30 Tage) find "\$BACKUP_DIR" -name "myp_backup_*.tar.gz" -mtime +30 -delete EOF chmod +x $LOCAL_BIN/myp-backup # Erstelle Cron-Job für automatische Backups echo "0 2 * * * root $LOCAL_BIN/myp-backup" > $CRON_DIR/myp-backup # Aktiviere und starte Services log "Aktiviere und starte Services..." systemctl daemon-reload systemctl enable "$SERVICE_NAME" systemctl enable nginx systemctl enable "$KIOSK_SERVICE_NAME" # Starte Services systemctl start "$SERVICE_NAME" systemctl start nginx # Warte kurz und prüfe Status sleep 5 if systemctl is-active --quiet "$SERVICE_NAME"; then log "✅ MYP Druckerverwaltung Service läuft" else warning "⚠️ MYP Druckerverwaltung Service nicht aktiv" fi if systemctl is-active --quiet nginx; then log "✅ Nginx läuft" else warning "⚠️ Nginx nicht aktiv" fi # Konfiguriere Firewall (falls ufw installiert) if command -v ufw &> /dev/null; then log "Konfiguriere Firewall..." ufw --force enable ufw allow 80/tcp ufw allow 22/tcp fi # Abschlussmeldung log "=== Installation abgeschlossen! ===" echo info "🎉 MYP Druckerverwaltung wurde erfolgreich installiert!" echo info "📋 Wichtige Informationen:" info " • Anwendung läuft auf: http://$(hostname -I | awk '{print $1}')" info " • Anwendungsverzeichnis: $APP_DIR" info " • Anwendungsbenutzer: $APP_USER" info " • Kiosk-Benutzer: $KIOSK_USER" info " • Service-Name: $SERVICE_NAME" info " • Kiosk-Service: $KIOSK_SERVICE_NAME" echo info "🔧 Wartungskommandos:" info " • Status prüfen: myp-maintenance status" info " • Neustart: myp-maintenance restart" info " • Logs anzeigen: myp-maintenance logs" info " • Kiosk-Logs: myp-maintenance kiosk-logs" info " • Nur Kiosk neustarten: myp-maintenance kiosk-restart" info " • Update: myp-maintenance update" info " • Backup erstellen: myp-backup" echo info "🔍 Zusätzliche Konfiguration:" info " • Kiosk-Skript: $KIOSK_HOME/kiosk.sh" info " • LightDM-Konfiguration: $LIGHTDM_CONF" info " • Openbox-Autostart: $KIOSK_HOME/.config/openbox/autostart" info " • Anwendungslogs: journalctl -u myp-druckerverwaltung -f" info " • Kiosk-Logs: journalctl -u myp-kiosk -f" echo warning "⚠️ Wichtiger Hinweis:" warning " Starte das System neu, um den Kiosk-Modus zu aktivieren:" warning " sudo reboot" echo log "Installation erfolgreich abgeschlossen! 🚀"