final-cleanup: Produktionsfertige Konfiguration - Alle Ports auf 443 vereinheitlicht, TLS-Zertifikate vorgeneriert, Zentraler Installer erstellt

This commit is contained in:
Till Tomczak 2025-05-26 22:16:22 +02:00
parent 7aa70cf976
commit f719f74195
40 changed files with 598 additions and 11815 deletions

View File

@ -1,379 +0,0 @@
# Common Errors und Lösungen
## 1. Database Schema Error - "no such column"
### Problem
```
sqlite3.OperationalError: no such column: printers_1.last_checked
[SQL: SELECT jobs.id AS jobs_id, ... printers_1.last_checked ...]
```
### Ursache
- Datenbankschema ist veraltet
- Die `last_checked` Spalte fehlt in der `printers` Tabelle
- Tritt auf, wenn die Datenbank vor Schema-Updates erstellt wurde
### Lösungen
1. **Automatische Migration (empfohlen):**
```bash
cd backend/app
PYTHONPATH=. python3.11 utils/database_migration.py
```
2. **Manuelle Datenbank-Neuerstellung:**
```bash
cd backend/app
python3.11 -c "from models import init_db; init_db(); print('Database recreated')"
python3.11 utils/setup_drucker_db.py
python3.11 -c "from models import create_initial_admin; create_initial_admin()"
```
3. **Spalte manuell hinzufügen:**
```bash
cd backend/app
python3.11 -c "
import sqlite3
conn = sqlite3.connect('database/myp.db')
cursor = conn.cursor()
cursor.execute('ALTER TABLE printers ADD COLUMN last_checked DATETIME')
conn.commit()
conn.close()
print('Column added')
"
```
### Prävention
- Verwende die Migrationsskripte vor dem Start der Anwendung
- Backup der Datenbank vor Schema-Änderungen erstellen
## 2. Tailwind CSS Compilation Fehler
### Problem
```
npm ERR! could not determine executable to run
```
### Ursache
- Node.js/npm nicht installiert oder nicht im PATH
- node_modules Verzeichnis fehlt
- Defekte npm Installation
### Lösungen
1. **Node.js installieren:**
```bash
# Ubuntu/Debian
sudo apt update && sudo apt install nodejs npm
# CentOS/RHEL
sudo yum install nodejs npm
```
2. **Dependencies neu installieren:**
```bash
cd backend/app
rm -rf node_modules package-lock.json
npm install
```
3. **Manuelle CSS-Kompilierung:**
```bash
cd backend/app
npx tailwindcss -i static/css/input.css -o static/css/tailwind.min.css --minify
```
4. **Fallback verwenden:**
- Die existierende `static/css/tailwind.min.css` wird automatisch verwendet
- Keine weiteren Schritte erforderlich
## 3. Port 443/80 Permission Denied
### Problem
```
Permission denied
```
beim Starten auf Port 443 oder 80
### Ursache
- Ports < 1024 sind privilegierte Ports
- Benötigen Root-Rechte oder spezielle Capabilities
### Lösungen
1. **Nicht-privilegierte Ports verwenden (empfohlen):**
```bash
python3 app.py --port 8443
```
2. **Automatische Fallback-Ports:**
- App erkennt automatisch Permission-Fehler
- Verwendet Port 8443 statt 443
- Verwendet Port 8080 statt 80
3. **Root-Rechte (nicht empfohlen):**
```bash
sudo python3 app.py
```
4. **Capabilities setzen (Linux):**
```bash
sudo setcap CAP_NET_BIND_SERVICE=+eip $(which python3)
```
## 4. Admin-Panel 404 Fehler
### Problem
```
404 Not Found
```
für Admin-Routen wie `/admin/users/add`, `/admin/printers/add`
### Ursache
- Fehlende Template-Dateien
- Nicht implementierte Admin-Routen
- Fehlende API-Endpunkte
### Lösungen
1. **Templates wurden erstellt:**
- `admin_add_user.html` - Benutzer hinzufügen
- `admin_add_printer.html` - Drucker hinzufügen
- `admin_edit_user.html` - Benutzer bearbeiten
- `admin_manage_printer.html` - Drucker verwalten
- `admin_printer_settings.html` - Drucker-Einstellungen
2. **API-Endpunkte implementiert:**
- `/api/admin/system/status` - System-Status
- `/api/admin/database/status` - Datenbank-Status
- `/api/admin/users/{id}/edit` - Benutzer bearbeiten
- `/api/admin/printers/{id}/edit` - Drucker bearbeiten
## 5. Admin-Variable-Fehler
### Problem
```
cannot access local variable 'os' where it is not associated with a value
```
### Ursache
- `os` Modul wird lokal importiert aber nicht verfügbar
### Lösung
- Import von `os` wurde an den Anfang der System-Informationen-Sektion verschoben
- Fehler ist behoben
## 6. Icon-Pfad 404 Fehler
### Problem
```
404 Not Found: /static/static/icons/icon-144x144.png
```
### Ursache
- Doppelte `static/` im Pfad in der `manifest.json`
### Lösung
- Pfade in `manifest.json` korrigiert von `static/icons/` zu `icons/`
- Icons sind jetzt korrekt erreichbar
## 7. SSL-Zertifikat Probleme
### Problem
- SSL-Zertifikate fehlen
- Zertifikat-Validierung schlägt fehl
### Lösungen
1. **Automatische Zertifikat-Generierung:**
- App erstellt automatisch selbstsignierte Zertifikate
- Für Entwicklung ausreichend
2. **SSL deaktivieren:**
```bash
python3 app.py --no-ssl
```
3. **Eigene Zertifikate verwenden:**
- Zertifikat: `backend/app/certs/myp.crt`
- Schlüssel: `backend/app/certs/myp.key`
## 8. Datenbank-Probleme
### Problem
- Datenbank kann nicht initialisiert werden
- SQLite-Fehler
### Lösungen
1. **Datenbank-Verzeichnis erstellen:**
```bash
mkdir -p backend/app/database
```
2. **Berechtigungen prüfen:**
```bash
chmod 755 backend/app/database
```
3. **Datenbank neu initialisieren:**
```bash
cd backend/app
python3 init_db.py
```
## 9. Scheduler-Fehler
### Problem
```
Task mit ID check_jobs existiert bereits
```
### Ursache
- App wurde mehrmals gestartet
- Scheduler-Thread läuft bereits
### Lösung
```bash
# Alle Python-Prozesse stoppen
pkill -f "python.*app.py"
# Neu starten
python3 app.py
```
## 10. Import-Fehler
### Problem
```
ModuleNotFoundError: No module named 'xyz'
```
### Lösung
```bash
# Python Dependencies installieren
cd backend/app
pip3 install -r requirements.txt
# Oder für Python 3.11
python3.11 -m pip install -r requirements.txt
```
## Startup-Script Verwendung
### Automatische Problembehandlung
```bash
# Einfachste Methode
./backend/run.sh
# Oder direkt
cd backend
python3 start_server.py
```
Das Startup-Script:
- Prüft automatisch Dependencies
- Findet verfügbare Ports
- Installiert fehlende Packages
- Kompiliert CSS falls möglich
- Startet Server mit optimalen Einstellungen
### Manuelle Parameter
```bash
# Spezifischer Port
python3 start_server.py --port 5000
# SSL deaktivieren
python3 start_server.py --no-ssl
# Dual-Protokoll (HTTP + HTTPS)
python3 start_server.py --dual-protocol
```
## Debugging-Tipps
1. **Log-Level erhöhen:**
```python
# In config/settings.py
LOG_LEVEL = "DEBUG"
```
2. **Detaillierte Logs anzeigen:**
```bash
tail -f backend/app/logs/app/app.log
```
3. **Netzwerk-Probleme prüfen:**
```bash
# Port-Status prüfen
netstat -tlnp | grep :8443
# Firewall prüfen
sudo ufw status
```
4. **Python-Umgebung prüfen:**
```bash
python3 --version
python3 -c "import flask; print(flask.__version__)"
```
## Neue Features (behoben)
### Admin-Panel Funktionalität
- ✅ Benutzer hinzufügen/bearbeiten
- ✅ Drucker hinzufügen/verwalten/konfigurieren
- ✅ System-Status und Datenbank-Status APIs
- ✅ Vollständige Admin-Templates
### Verbesserte Fehlerbehandlung
- ✅ Automatische Port-Fallbacks
- ✅ Graceful CSS-Kompilierung mit Fallback
- ✅ Robuste SSL-Zertifikat-Behandlung
- ✅ Verbesserte Logging und Debugging
## Flask Route Konflikte - 404 Fehler bei existierenden Routen
**Problem:**
- API-Endpunkt `/api/admin/stats/live` gibt 404 Fehler zurück, obwohl die Route implementiert ist
- Flask-Anwendung startet nicht mit AssertionError: "View function mapping is overwriting an existing endpoint function"
**Ursache:**
- Doppelte Route-Definitionen in `app.py` (z.B. `update_printers` mehrfach definiert)
- Konflikte zwischen Haupt-App-Routen und Blueprint-Routen
- API-Blueprint wird ohne URL-Präfix registriert und überschreibt Haupt-Routen
**Lösung:**
1. **Doppelte Routen entfernen:**
```bash
grep -n "def update_printers" app.py # Finde alle Duplikate
sed -i '3512,$d' app.py # Entferne doppelte Definition am Ende
```
2. **Blueprint-Registrierung deaktivieren:**
```python
# app.register_blueprint(api_bp) # Kommentiere aus bei Konflikten
```
3. **Route-Registrierung prüfen:**
```python
python3.11 -c "from app import app; [print(f'{rule.rule} -> {rule.endpoint}') for rule in app.url_map.iter_rules() if 'admin' in rule.rule and 'stats' in rule.rule]"
```
**Prävention:**
- Verwende eindeutige Funktionsnamen
- Registriere Blueprints mit URL-Präfix: `app.register_blueprint(api_bp, url_prefix='/api/v1')`
- Prüfe Route-Konflikte vor Deployment
**Behoben am:** 26.05.2025
**Betroffen:** Flask-Anwendung, Admin-Dashboard, Live-Statistiken
**Status:** ✅ GELÖST - API-Blueprint registriert mit URL-Präfix /api/v1, alle Admin-CRUD-Endpunkte funktionieren
**Fix angewendet:** 26.05.2025
- API-Blueprint in app.py korrekt registriert mit `app.register_blueprint(api_bp, url_prefix='/api/v1')`
- Alle Admin-Dashboard API-Endpunkte sind jetzt verfügbar:
- `/api/admin/stats/live`
- `/api/admin/system/status`
- `/api/admin/database/status`
- Alle Admin-Template-Routen funktionieren:
- `/admin/users/add`
- `/admin/users/<id>/edit`
- `/admin/printers/add`
- `/admin/printers/<id>/manage`
**Prävention:** Regelmäßige Überprüfung der Blueprint-Registrierung beim Hinzufügen neuer Routen

259
README.md
View File

@ -1,259 +0,0 @@
# MYP (Mercedes-Benz Yard Printing) Platform
Eine vollständige 3D-Drucker-Management-Plattform für Mercedes-Benz Werk 040 Berlin.
## Schnellstart
### Windows (PowerShell)
```powershell
# Als Administrator für vollständige Funktionalität
.\myp_installer.ps1
```
### Linux/Unix/macOS (Bash)
```bash
# Ausführbar machen und als Root für vollständige Funktionalität
chmod +x myp_installer.sh
sudo ./myp_installer.sh
```
Die konsolidierten Installer bieten folgende Funktionen:
- Systemvoraussetzungen prüfen
- Host-Konfiguration einrichten
- SSL-Zertifikate erstellen und verwalten
- Backend-Verbindung testen
- Frontend-/Backend-URL konfigurieren
- Debug-Server starten
- Vollständige MYP-Installation
- Umgebungs-Setup (Abhängigkeiten installieren)
- Anwendung starten (verschiedene Modi)
- Alte Dateien bereinigen
## Übersicht
Die MYP-Plattform ist eine moderne, webbasierte Lösung zur Verwaltung von 3D-Druckern in einer Unternehmensumgebung. Sie bietet:
- **Drucker-Management**: Überwachung und Steuerung von 3D-Druckern
- **Auftragsverwaltung**: Verwaltung von Druckaufträgen und Warteschlangen
- **Benutzerauthentifizierung**: GitHub OAuth und lokale Benutzerkonten
- **Smart-Plug-Integration**: Automatische Stromsteuerung über TP-Link Tapo-Steckdosen
- **SSL/HTTPS-Unterstützung**: Sichere Kommunikation mit selbstsignierten Zertifikaten
## Architektur
### Backend
- **Framework**: Flask (Python)
- **Datenbank**: SQLite
- **API**: RESTful API mit JSON
- **Authentifizierung**: Session-basiert mit Flask-Login
- **SSL**: Selbstsignierte Zertifikate
### Frontend
- **Framework**: Next.js (React)
- **Styling**: Tailwind CSS
- **Authentifizierung**: GitHub OAuth
- **API-Kommunikation**: Fetch API
## Installation
### Automatische Installation
Die einfachste Methode ist die Verwendung der konsolidierten Installer-Skripte:
#### Windows (PowerShell)
```powershell
# Als Administrator ausführen für vollständige Funktionalität
.\myp_installer.ps1
```
#### Linux/Unix/macOS (Bash)
```bash
# Ausführbar machen
chmod +x myp_installer.sh
# Als Root für vollständige Funktionalität
sudo ./myp_installer.sh
```
### Manuelle Installation
#### Voraussetzungen
- Python 3.6+ mit pip
- Node.js 16+ mit npm
- Docker und Docker Compose (optional)
- Git
#### Backend-Setup
```bash
cd backend
pip install -r requirements.txt
python app/app.py
```
#### Frontend-Setup
```bash
cd frontend
npm install
npm run dev
```
## Konfiguration
### Standard-Zugangsdaten
- **Admin E-Mail**: admin@mercedes-benz.com
- **Admin Passwort**: 744563017196A
### Umgebungsvariablen
#### Backend (.env)
```
SECRET_KEY=7445630171969DFAC92C53CEC92E67A9CB2E00B3CB2F
DATABASE_PATH=database/myp.db
TAPO_USERNAME=till.tomczak@mercedes-benz.com
TAPO_PASSWORD=744563017196A
SSL_ENABLED=True
```
#### Frontend (.env.local)
```
NEXT_PUBLIC_API_URL=https://localhost:443
NEXT_PUBLIC_BACKEND_HOST=localhost
NEXT_PUBLIC_BACKEND_PROTOCOL=https
GITHUB_CLIENT_ID=7c5d8bef1a5519ec1fdc
GITHUB_CLIENT_SECRET=5f1e586204358fbd53cf5fb7d418b3f06ccab8fd
```
## SSL-Zertifikate
Die Plattform verwendet selbstsignierte SSL-Zertifikate für sichere Kommunikation. Diese werden automatisch von den Installer-Skripten erstellt.
### Manuelle Zertifikatserstellung
```bash
cd backend
python app/create_ssl_cert.py -c instance/ssl/myp.crt -k instance/ssl/myp.key -n localhost
```
## Docker-Deployment
```bash
# Entwicklung
docker-compose up -d
# Produktion
docker-compose -f docker-compose.prod.yml up -d
```
## Entwicklung
### Backend-Entwicklung
```bash
cd backend
python app/app.py --debug
```
### Frontend-Entwicklung
```bash
cd frontend
npm run dev
```
### Tests ausführen
```bash
# Backend-Tests
cd backend
python -m pytest
# Frontend-Tests
cd frontend
npm test
```
## API-Dokumentation
Die REST API ist unter `/api/docs` verfügbar, wenn der Backend-Server läuft.
### Wichtige Endpunkte
- `GET /api/printers` - Liste aller Drucker
- `POST /api/jobs` - Neuen Druckauftrag erstellen
- `GET /api/jobs/{id}` - Auftragsstatus abrufen
- `POST /api/auth/login` - Benutzeranmeldung
## Fehlerbehebung
### Häufige Probleme
#### SSL-Zertifikatsfehler
```bash
# Zertifikate neu erstellen
python backend/app/create_ssl_cert.py -c backend/instance/ssl/myp.crt -k backend/instance/ssl/myp.key -n localhost
```
#### Port bereits in Verwendung
```bash
# Prozesse auf Port 443 beenden
sudo lsof -ti:443 | xargs kill -9
```
#### Datenbankfehler
```bash
# Datenbank zurücksetzen
rm backend/database/myp.db
python backend/app/models.py
```
## Sicherheit
- Alle Passwörter sind in `CREDENTIALS.md` dokumentiert
- SSL/TLS-Verschlüsselung für alle Verbindungen
- Session-basierte Authentifizierung
- Rate Limiting für API-Endpunkte
## Lizenz
Dieses Projekt ist für den internen Gebrauch bei Mercedes-Benz AG bestimmt.
## Support
Bei Problemen oder Fragen wenden Sie sich an das Entwicklungsteam oder erstellen Sie ein Issue im Repository.
## Changelog
### Version 3.0
- Konsolidierte Installer-Skripte
- Verbesserte SSL-Unterstützung
- GitHub OAuth-Integration
- Erweiterte Drucker-Management-Funktionen
### Version 2.0
- Frontend-Neugestaltung mit Next.js
- REST API-Implementierung
- Docker-Unterstützung
### Version 1.0
- Grundlegende Drucker-Management-Funktionen
- Flask-Backend
- SQLite-Datenbank

View File

@ -1,169 +0,0 @@
# MYP System - Roadmap
## ✅ Abgeschlossen (Version 2.0)
### Architektur-Vereinfachung
- [x] **Blueprint-Integration**: Alle Flask Blueprints in zentrale `app.py` integriert
- [x] **Code-Konsolidierung**: Über 25 Routen in einer Datei vereint
- [x] **Struktur-Optimierung**: Verbesserte Wartbarkeit und Übersichtlichkeit
### Datenbank-Verbesserungen (KRITISCH)
- [x] **Write-Ahead Logging (WAL)**: SQLite WAL-Modus für bessere Concurrency
- [x] **Connection Pooling**: Optimierte SQLAlchemy-Engine mit 20+30 Verbindungen
- [x] **Intelligentes Caching**: Thread-sicheres Caching-System mit automatischer Invalidierung
- [x] **Automatisches Backup-System**: Tägliche komprimierte Backups mit 30-Tage Rotation
- [x] **Datenbank-Monitoring**: Gesundheitsprüfung und Performance-Überwachung
- [x] **Automatische Wartung**: Hintergrund-Scheduler für Optimierung und Maintenance
- [x] **Admin-API**: Vollständige REST-API für Datenbank-Verwaltung
### Performance-Optimierungen
- [x] **Cache-Strategien**:
- User-Daten: 5-10 Minuten
- Printer-Status: 1-2 Minuten
- Job-Daten: 30 Sekunden - 5 Minuten
- Statistiken: 10 Minuten
- [x] **SQLite-Tuning**: 64MB Cache, Memory Mapping, Foreign Keys
- [x] **Query-Optimierung**: Automatische ANALYZE und PRAGMA optimize
### Sicherheit & Stabilität
- [x] **Backup-Sicherheit**: Komprimierte Backups mit Pfad-Validierung
- [x] **Datenintegrität**: Regelmäßige Integritätsprüfungen
- [x] **Fehlerbehandlung**: Umfassendes Logging und Error Recovery
- [x] **Admin-Berechtigung**: Sichere API-Endpunkte für kritische Operationen
## 🚀 Aktuelle Features (Version 2.0)
### Core-Funktionalitäten
- ✅ Benutzer-Authentifizierung und -Verwaltung
- ✅ Drucker-Management mit Live-Status
- ✅ Job-Verwaltung (Erstellen, Bearbeiten, Verlängern, Löschen)
- ✅ Admin-Panel mit erweiterten Funktionen
- ✅ Kiosk-Modus für öffentliche Terminals
- ✅ Vollständige API für Frontend-Integration
- ✅ Robuste Fehlerbehandlung und Logging
### Datenbank-Features
- ✅ WAL-Modus für bessere Performance
- ✅ Automatische Backups und Wiederherstellung
- ✅ Intelligentes Caching-System
- ✅ Performance-Monitoring
- ✅ Automatische Wartung und Optimierung
### API-Endpunkte
- ✅ **Authentifizierung**: `/auth/login`, `/auth/logout`
- ✅ **Benutzer**: `/user/profile`, `/user/settings`
- ✅ **Jobs**: `/api/jobs`, `/api/jobs/<id>`
- ✅ **Drucker**: `/api/printers`, `/api/printers/<id>`
- ✅ **Admin**: `/api/admin/users`, `/api/admin/stats`
- ✅ **Kiosk**: `/api/kiosk/status`, `/api/kiosk/activate`
- ✅ **Datenbank**: `/api/admin/database/*` (Backup, Stats, Health)
## 📊 Performance-Metriken (Version 2.0)
### Verbesserungen gegenüber Version 1.0
- **50-80% schnellere Abfragen** durch Caching
- **Verbesserte Concurrency** durch WAL-Modus
- **Automatische Wartung** reduziert manuelle Eingriffe um 90%
- **Proaktive Überwachung** verhindert 95% der Ausfälle
### Aktuelle Benchmarks
- Durchschnittliche Response-Zeit: <100ms
- Cache-Hit-Rate: >80%
- Backup-Erfolgsrate: 100%
- System-Verfügbarkeit: >99.9%
## 🎯 Geplante Features (Version 2.1)
### Frontend-Verbesserungen
- [ ] **React/Next.js Migration**: Moderne Frontend-Architektur
- [ ] **Real-time Updates**: WebSocket-Integration für Live-Updates
- [ ] **Mobile Responsiveness**: Optimierung für mobile Geräte
- [ ] **Dark Mode**: Benutzerfreundliche Themes
### Erweiterte Datenbank-Features
- [ ] **Replikation**: High Availability Setup
- [ ] **Metriken-Dashboard**: Real-time Performance-Monitoring
- [ ] **Adaptive Caching**: Intelligente Cache-Größenanpassung
- [ ] **Cloud-Backup**: Integration mit Cloud-Storage
### Neue Funktionalitäten
- [ ] **Benachrichtigungssystem**: E-Mail/SMS-Alerts
- [ ] **Reporting**: Erweiterte Statistiken und Reports
- [ ] **Multi-Tenant**: Support für mehrere Organisationen
- [ ] **API-Versionierung**: RESTful API v2
## 🔧 Technische Verbesserungen (Version 2.1)
### Architektur
- [ ] **Microservices**: Aufteilen in kleinere Services
- [ ] **Container-Orchestrierung**: Kubernetes-Support
- [ ] **Load Balancing**: Horizontale Skalierung
- [ ] **Service Mesh**: Istio-Integration
### Monitoring & Observability
- [ ] **Prometheus Integration**: Metriken-Sammlung
- [ ] **Grafana Dashboards**: Visualisierung
- [ ] **Distributed Tracing**: Jaeger-Integration
- [ ] **Log Aggregation**: ELK-Stack
### Sicherheit
- [ ] **OAuth2/OIDC**: Moderne Authentifizierung
- [ ] **RBAC**: Role-Based Access Control
- [ ] **Audit Logging**: Compliance-Features
- [ ] **Encryption**: End-to-End Verschlüsselung
## 🚨 Kritische Prioritäten
### Sofort (Version 2.0.1)
1. **Monitoring-Dashboard**: Admin-Interface für DB-Metriken
2. **Backup-Validierung**: Automatische Backup-Tests
3. **Performance-Alerts**: Proaktive Benachrichtigungen
### Kurzfristig (Version 2.1)
1. **Frontend-Modernisierung**: React/Next.js Migration
2. **Real-time Features**: WebSocket-Integration
3. **Mobile Optimierung**: Responsive Design
### Mittelfristig (Version 2.2)
1. **High Availability**: Replikation und Failover
2. **Erweiterte Analytics**: Business Intelligence
3. **Multi-Tenant Support**: Organisationsverwaltung
### Langfristig (Version 3.0)
1. **Cloud-Native**: Kubernetes-Deployment
2. **Microservices**: Service-orientierte Architektur
3. **AI/ML Integration**: Predictive Analytics
## 📈 Erfolgsmetriken
### Technische KPIs
- **Verfügbarkeit**: >99.9%
- **Response-Zeit**: <100ms (95. Perzentil)
- **Fehlerrate**: <0.1%
- **Cache-Hit-Rate**: >80%
### Business KPIs
- **Benutzer-Zufriedenheit**: >4.5/5
- **System-Adoption**: >90%
- **Support-Tickets**: <5/Monat
- **Wartungszeit**: <2h/Monat
## 🛠 Entwicklungsrichtlinien
### Code-Qualität
- **Test-Coverage**: >90%
- **Code-Review**: Mandatory für alle Changes
- **Documentation**: Vollständige API-Dokumentation
- **Security**: Regelmäßige Security-Audits
### Deployment
- **CI/CD**: Automatisierte Pipelines
- **Blue-Green**: Zero-Downtime Deployments
- **Rollback**: Schnelle Rollback-Mechanismen
- **Monitoring**: Kontinuierliche Überwachung
---
**Letzte Aktualisierung**: Dezember 2024
**Version**: 2.0
**Status**: ✅ Datenbank-Verbesserungen vollständig implementiert

View File

@ -1,120 +0,0 @@
# MYP - Manage Your Printer
Ein System zur Verwaltung und Steuerung von 3D-Druckern über TP-Link Tapo P110 Smart Plugs.
## Verzeichnisstruktur
Diese MYP-Installation ist wie folgt organisiert:
- **app/** - Enthält den Anwendungscode (app.py, models.py)
- **docs/** - Enthält die Dokumentation (README, Anleitungen, Fehlerbehebung)
- **install/** - Enthält Installationsskripte und Konfigurationsdateien
## Installation
Zur Installation und Konfiguration nutzen Sie bitte das Hauptinstallationsskript:
```bash
chmod +x setup_myp.sh
./setup_myp.sh
```
Das Skript führt Sie durch die verfügbaren Optionen:
1. Standardinstallation (nur MYP-Anwendung)
2. Kiosk-Modus Installation (vollautomatischer Start nach Boot)
3. Dokumentation anzeigen
## Ausführliche Dokumentation
Die vollständige Dokumentation finden Sie im `docs/`-Verzeichnis:
- Allgemeine Anleitung: [docs/README.md](docs/README.md)
- Kiosk-Modus Anleitung: [docs/KIOSK-SETUP.md](docs/KIOSK-SETUP.md)
- Fehlerbehebung: [docs/COMMON_ERRORS.md](docs/COMMON_ERRORS.md)
- Entwicklungsplan: [docs/ROADMAP.md](docs/ROADMAP.md)
## Funktionsumfang
- Benutzer- und Rechteverwaltung (Admin/User)
- Verwaltung von Druckern und Smart Plugs
- Reservierungssystem für Drucker (Zeitplanung)
- Automatisches Ein-/Ausschalten der Drucker über Smart Plugs
- Statistikerfassung für Druckaufträge
- **NEU**: Kiosk-Modus für automatischen Start auf Raspberry Pi
## Systemvoraussetzungen
- Raspberry Pi 4 (oder kompatibel)
- Python 3.11+
- Internetzugang für die Installation (danach offline nutzbar)
- TP-Link Tapo P110 Smart Plugs im lokalen Netzwerk
## Erster Start
Beim ersten Start wird eine leere Datenbank angelegt. Es muss ein erster Administrator angelegt werden:
```
POST /api/create-initial-admin
```
Mit folgendem JSON-Body:
```json
{
"email": "admin@example.com",
"password": "sicheres-passwort",
"name": "Administrator"
}
```
## API-Dokumentation
Die Anwendung stellt folgende REST-API-Endpunkte bereit:
### Authentifizierung
- `POST /auth/register` - Neuen Benutzer registrieren
- `POST /auth/login` - Anmelden (erstellt eine Session für 7 Tage)
### Drucker
- `GET /api/printers` - Alle Drucker auflisten
- `GET /api/printers/<printerId>` - Einzelnen Drucker abrufen
- `POST /api/printers` - Neuen Drucker anlegen
- `DELETE /api/printers/<printerId>` - Drucker löschen
### Jobs/Reservierungen
- `GET /api/jobs` - Alle Reservierungen abrufen
- `POST /api/jobs` - Neue Reservierung anlegen
- `GET /api/jobs/<jobId>` - Reservierungsdetails abrufen
- `POST /api/jobs/<jobId>/finish` - Job beenden (Plug ausschalten)
- `POST /api/jobs/<jobId>/abort` - Job abbrechen (Plug ausschalten)
- `POST /api/jobs/<jobId>/extend` - Endzeit verschieben
- `GET /api/jobs/<jobId>/status` - Aktuellen Plug-Status abrufen
- `GET /api/jobs/<jobId>/remaining-time` - Restzeit in Sekunden abrufen
- `DELETE /api/jobs/<jobId>` - Job löschen
### Benutzer
- `GET /api/users` - Alle Benutzer auflisten (nur Admin)
- `GET /api/users/<userId>` - Einzelnen Benutzer abrufen
- `DELETE /api/users/<userId>` - Benutzer löschen (nur Admin)
### Sonstiges
- `GET /api/stats` - Globale Statistik (Druckzeit, etc.)
- `GET /api/test` - Health-Check
## Sicherheitshinweise
- Diese Anwendung speichert alle Zugangsdaten direkt im Code und in der Datenbank.
- Die Anwendung sollte ausschließlich in einem geschützten, lokalen Netzwerk betrieben werden.
- Es wird keine Verschlüsselung für die API-Kommunikation verwendet.
## Wartung und Troubleshooting
- Die Logdatei `myp.log` enthält alle wichtigen Ereignisse und Fehler
- Die Datenbank wird in `database/myp.db` gespeichert
- Häufig auftretende Probleme und Lösungen finden sich in [COMMON_ERRORS.md](COMMON_ERRORS.md)
- Zukünftige Entwicklungspläne sind in [ROADMAP.md](ROADMAP.md) dokumentiert

View File

@ -1,276 +0,0 @@
# Datenbank-Verbesserungen - MYP System
## Übersicht
Das MYP-System wurde mit umfassenden Datenbank-Verbesserungen ausgestattet, die Stabilität, Sicherheit und Performance erheblich steigern. Diese Dokumentation beschreibt alle implementierten Features.
## 🚀 Implementierte Features
### 1. Write-Ahead Logging (WAL)
- **Aktiviert**: SQLite WAL-Modus für bessere Concurrency
- **Vorteile**:
- Gleichzeitige Lese- und Schreiboperationen
- Bessere Performance bei hoher Last
- Reduzierte Sperrzeiten
- **Konfiguration**: Automatisch aktiviert in `models.py`
### 2. Connection Pooling
- **Engine-Optimierung**: Konfigurierte SQLAlchemy-Engine mit Pooling
- **Parameter**:
- Pool-Größe: 20 Verbindungen
- Max Overflow: 30 zusätzliche Verbindungen
- Connection Timeout: 30 Sekunden
- Pool Recycle: 3600 Sekunden
### 3. Intelligentes Caching-System
- **Thread-sicherer Cache**: Implementiert mit `threading.local()`
- **Cache-Strategien**:
- User-Daten: 5-10 Minuten
- Printer-Status: 1-2 Minuten
- Job-Daten: 30 Sekunden - 5 Minuten
- Statistiken: 10 Minuten
- **Cache-Invalidierung**: Automatisch bei Datenänderungen
### 4. Automatisches Backup-System
- **Tägliche Backups**: Automatisch um Mitternacht
- **Komprimierung**: Gzip-Komprimierung für Speichereffizienz
- **Rotation**: Automatische Bereinigung alter Backups (30 Tage)
- **Manueller Trigger**: Admin-Interface für sofortige Backups
### 5. Datenbank-Monitoring
- **Gesundheitsprüfung**: Integritätschecks und Performance-Monitoring
- **Statistiken**: Detaillierte DB-Metriken
- **Wartungsalerts**: Automatische Benachrichtigungen bei Problemen
### 6. Automatische Wartung
- **Scheduler**: Hintergrund-Thread für Wartungsaufgaben
- **Operationen**:
- ANALYZE für Query-Optimierung
- WAL-Checkpoints
- Incremental Vacuum
- PRAGMA optimize
## 📁 Dateistruktur
```
backend/app/
├── models.py # Erweiterte Modelle mit Caching
├── utils/
│ └── database_utils.py # Backup & Monitoring Utilities
├── database/
│ ├── myp_database.db # Hauptdatenbank
│ ├── myp_database.db-wal # WAL-Datei
│ ├── myp_database.db-shm # Shared Memory
│ └── backups/ # Backup-Verzeichnis
│ ├── myp_backup_20241201_120000.db.gz
│ └── ...
```
## 🔧 Konfiguration
### SQLite-Optimierungen
```sql
PRAGMA journal_mode = WAL;
PRAGMA synchronous = NORMAL;
PRAGMA cache_size = -64000; # 64MB Cache
PRAGMA temp_store = MEMORY;
PRAGMA mmap_size = 268435456; # 256MB Memory Map
PRAGMA foreign_keys = ON;
```
### Cache-Konfiguration
```python
# Cache-Zeiten (Sekunden)
USER_CACHE_TIME = 300 # 5 Minuten
PRINTER_CACHE_TIME = 120 # 2 Minuten
JOB_CACHE_TIME = 180 # 3 Minuten
STATS_CACHE_TIME = 600 # 10 Minuten
```
## 🛠 API-Endpunkte
### Datenbank-Statistiken
```http
GET /api/admin/database/stats
```
**Response:**
```json
{
"success": true,
"stats": {
"database_size_mb": 15.2,
"wal_size_mb": 2.1,
"journal_mode": "wal",
"cache_size": -64000,
"table_counts": {
"users": 25,
"printers": 8,
"jobs": 1247
}
}
}
```
### Gesundheitsprüfung
```http
GET /api/admin/database/health
```
**Response:**
```json
{
"success": true,
"health": {
"status": "healthy",
"issues": [],
"recommendations": []
}
}
```
### Backup erstellen
```http
POST /api/admin/database/backup
Content-Type: application/json
{
"compress": true
}
```
### Backup-Liste abrufen
```http
GET /api/admin/database/backups
```
### Backup wiederherstellen
```http
POST /api/admin/database/backup/restore
Content-Type: application/json
{
"backup_path": "/path/to/backup.db.gz"
}
```
### Datenbank optimieren
```http
POST /api/admin/database/optimize
```
### Alte Backups bereinigen
```http
POST /api/admin/database/backup/cleanup
Content-Type: application/json
{
"keep_days": 30
}
```
## 📊 Performance-Verbesserungen
### Vor den Verbesserungen
- Einzelne DB-Verbindung
- Keine Caching-Mechanismen
- Manuelle Backups erforderlich
- Keine Performance-Überwachung
### Nach den Verbesserungen
- **50-80% schnellere Abfragen** durch Caching
- **Verbesserte Concurrency** durch WAL-Modus
- **Automatische Wartung** reduziert manuelle Eingriffe
- **Proaktive Überwachung** verhindert Ausfälle
## 🔒 Sicherheitsfeatures
### Backup-Sicherheit
- Komprimierte Backups reduzieren Speicherbedarf
- Automatische Rotation verhindert Speicherüberläufe
- Sicherheitsbackup vor Wiederherstellung
### Zugriffskontrolle
- Alle Admin-Endpunkte erfordern Admin-Berechtigung
- Pfad-Validierung bei Backup-Operationen
- Fehlerbehandlung mit detailliertem Logging
### Datenintegrität
- Regelmäßige Integritätsprüfungen
- WAL-Modus verhindert Datenverlust
- Foreign Key Constraints aktiviert
## 🚨 Monitoring & Alerts
### Automatische Überwachung
- **WAL-Dateigröße**: Alert bei >100MB
- **Freier Speicherplatz**: Warnung bei <1GB
- **Integritätsprüfung**: Tägliche Checks
- **Performance-Metriken**: Kontinuierliche Sammlung
### Log-Kategorien
```
[DATABASE] - Allgemeine Datenbank-Operationen
[BACKUP] - Backup-Operationen
[CACHE] - Cache-Operationen
[MAINTENANCE] - Wartungsaufgaben
[HEALTH] - Gesundheitsprüfungen
```
## 🔄 Wartungsplan
### Automatisch (Hintergrund)
- **Täglich**: Backup, Optimierung, Gesundheitsprüfung
- **Wöchentlich**: Bereinigung alter Backups
- **Stündlich**: Cache-Bereinigung, WAL-Checkpoints
### Manuell (Admin-Interface)
- Sofortige Backups vor kritischen Änderungen
- Manuelle Optimierung bei Performance-Problemen
- Backup-Wiederherstellung bei Datenverlust
## 📈 Metriken & KPIs
### Performance-Indikatoren
- Durchschnittliche Query-Zeit
- Cache-Hit-Rate
- WAL-Checkpoint-Häufigkeit
- Backup-Erfolgsrate
### Kapazitätsplanung
- Datenbankwachstum pro Monat
- Backup-Speicherverbrauch
- Cache-Effizienz
## 🛡 Disaster Recovery
### Backup-Strategie
1. **Tägliche automatische Backups**
2. **30-Tage Aufbewahrung**
3. **Komprimierte Speicherung**
4. **Schnelle Wiederherstellung**
### Recovery-Prozess
1. System stoppen
2. Backup auswählen
3. Wiederherstellung durchführen
4. Integritätsprüfung
5. System neu starten
## 🎯 Nächste Schritte
### Geplante Erweiterungen
- [ ] Replikation für High Availability
- [ ] Erweiterte Metriken-Dashboard
- [ ] Automatische Performance-Tuning
- [ ] Cloud-Backup-Integration
### Optimierungsmöglichkeiten
- [ ] Adaptive Cache-Größen
- [ ] Intelligente Backup-Zeitpunkte
- [ ] Predictive Maintenance
- [ ] Real-time Monitoring Dashboard
---
**Status**: ✅ Vollständig implementiert und getestet
**Version**: 2.0
**Letzte Aktualisierung**: Dezember 2024

View File

@ -1,127 +0,0 @@
# MYP Platform - 3D-Drucker Reservierungssystem
Ein Reservierungssystem für 3D-Drucker, das automatisch TP-Link Tapo P110 Smart Plugs steuert, um die Stromversorgung von Druckern basierend auf den reservierten Zeitslots zu verwalten.
## Features
- Reservierung von 3D-Druckern für bestimmte Zeiträume
- Automatische Steuerung der TP-Link Tapo P110 Smart Plugs
- Echtzeit-Überwachung von laufenden Druckaufträgen
- Administrationsbereich für Druckerverwaltung
- Benutzerauthentifizierung und Autorisierung
- Statistiken zu Druckaufträgen und Materialverbrauch
- Dark Mode für eine angenehme Nutzung bei schlechten Lichtverhältnissen
- Responsive Design für verschiedene Gerätegrößen
## Technologie-Stack
- **Backend**: Python 3.11 mit Flask
- **Frontend**: HTML/CSS/JavaScript mit Tailwind CSS
- **Datenbank**: SQLite mit SQLAlchemy ORM
- **Authentifizierung**: Flask-Login
- **Hardware-Integration**: PyP100 für Tapo Smart Plug Steuerung
- **Automatisierung**: Integrierter Job-Scheduler für Drucker-Steuerung
## Systemanforderungen
- Python 3.11+
- Node.js und npm (für Tailwind CSS)
- Netzwerkzugang zu TP-Link Tapo P110 Smart Plugs
- Unterstützte Betriebssysteme: Linux, Windows, macOS
## Installation
1. **Repository klonen**:
```bash
git clone <repository-url>
cd myp-platform
```
2. **Python-Abhängigkeiten installieren**:
```bash
cd backend/app
pip install -r requirements.txt
```
3. **Node-Abhängigkeiten installieren und CSS bauen**:
```bash
npm install
npm run build:css
```
4. **Datenbank initialisieren**:
```bash
python init_db.py
```
5. **Server starten**:
```bash
# Standardstart
python app.py
# Oder mit spezifischem Port (empfohlen)
python app.py --port=5000
```
## API Endpunkte
| Methode | Endpunkt | Beschreibung |
|---------|------------------------|--------------------------------------------------------|
| GET | /api/jobs | Gibt alle Jobs (für Admins) oder eigene Jobs zurück |
| GET | /api/jobs/active | Gibt alle aktiven Druckaufträge zurück |
| GET | /api/jobs/{id} | Gibt Details zu einem bestimmten Job zurück |
| POST | /api/jobs | Erstellt eine neue Druckerreservierung |
| GET | /api/printers | Gibt alle verfügbaren Drucker zurück |
## Scheduler
Das System enthält einen eingebauten Scheduler, der automatisch:
- Drucker einschaltet, wenn ein Auftrag beginnt
- Drucker ausschaltet, wenn ein Auftrag endet
- Den Status von Druckern aktualisiert
- Die Auftragsstatistiken sammelt
## Konfiguration
Die Konfiguration erfolgt über die Datei `config/settings.py`. Wichtige Einstellungen umfassen:
- Datenbankpfad
- Tapo-Zugangsdaten
- Drucker-Konfigurationen
- Logging-Einstellungen
- Webserver-Einstellungen
## CSS-System
Die Anwendung nutzt Tailwind CSS für das Styling mit separaten Dateien für Light- und Dark-Mode.
### Tailwind Build
```bash
# CSS bauen
npm run build:css
# CSS im Watch-Modus (für Entwicklung)
npm run watch:css
```
## Sicherheit
- Nur angemeldete Benutzer können Druckaufträge erstellen
- Nur Besitzer eines Druckauftrags können diesen verwalten
- Nur Administratoren haben Zugriff auf alle Jobs und Systemeinstellungen
- Passwörter werden mit bcrypt gesichert
## Fehlerbehandlung und Logging
Das System führt detaillierte Logs in folgenden Kategorien:
- App-Log (allgemeine Anwendungslogs)
- Auth-Log (Authentifizierungsereignisse)
- Jobs-Log (Druckauftragsoperationen)
- Printer-Log (Druckerstatusänderungen)
- Scheduler-Log (Automatisierungsaktionen)
- Error-Log (Fehlerprotokollierung)
## Entwicklung
Diese Anwendung ist für den Offline-Betrieb konzipiert und verwendet keine externen CDNs.
Weitere Informationen zur Entwicklungsumgebung finden Sie in der `TAILWIND_SETUP.md`.

View File

@ -18,35 +18,21 @@ class AdminLiveDashboard {
}
detectApiBaseUrl() {
// Versuche verschiedene Ports zu erkennen
const currentHost = window.location.hostname;
const currentPort = window.location.port;
const currentProtocol = window.location.protocol;
const currentPort = window.location.port;
console.log('🔍 Aktuelle URL-Informationen:', {
host: currentHost,
port: currentPort,
protocol: currentProtocol,
fullUrl: window.location.href
});
console.log('🔍 Live Dashboard API URL Detection:', { currentHost, currentProtocol, currentPort });
// Wenn wir bereits auf dem richtigen Port sind, verwende relative URLs
if (currentPort === '5000' || !currentPort) {
console.log('✅ Verwende relative URLs (gleicher Port oder Standard)');
if (currentPort === '443' || !currentPort) {
console.log('✅ Verwende relative URLs (HTTPS Port 443)');
return '';
}
// Wenn wir auf 8443 sind, versuche 5000 (häufiger Fall)
if (currentPort === '8443') {
const fallbackUrl = `http://${currentHost}:5000`;
console.log('🔄 Fallback von HTTPS:8443 zu HTTP:5000:', fallbackUrl);
return fallbackUrl;
}
// Für andere Ports, verwende Standard-Backend-Port
const defaultPort = currentProtocol === 'https:' ? '8443' : '5000';
const fallbackUrl = `${currentProtocol}//${currentHost}:${defaultPort}`;
console.log('🔄 Standard-Fallback:', fallbackUrl);
// Für alle anderen Fälle, verwende HTTPS auf Port 443
const fallbackUrl = `https://${currentHost}`;
console.log('🔄 Fallback zu HTTPS:443:', fallbackUrl);
return fallbackUrl;
}

View File

@ -12,34 +12,20 @@ let csrfToken;
// Dynamische API-Base-URL-Erkennung
function detectApiBaseUrl() {
const currentHost = window.location.hostname;
const currentPort = window.location.port;
const currentProtocol = window.location.protocol;
const currentPort = window.location.port;
console.log('🔍 Admin API URL-Informationen:', {
host: currentHost,
port: currentPort,
protocol: currentProtocol,
fullUrl: window.location.href
});
console.log('🔍 Admin API URL Detection:', { currentHost, currentProtocol, currentPort });
// Wenn wir bereits auf dem richtigen Port sind, verwende relative URLs
if (currentPort === '5000' || !currentPort) {
console.log('✅ Verwende relative URLs (gleicher Port oder Standard)');
if (currentPort === '443' || !currentPort) {
console.log('✅ Verwende relative URLs (HTTPS Port 443)');
return '';
}
// Wenn wir auf 8443 sind, versuche 5000 (häufiger Fall)
if (currentPort === '8443') {
const fallbackUrl = `http://${currentHost}:5000`;
console.log('🔄 Admin Fallback von HTTPS:8443 zu HTTP:5000:', fallbackUrl);
return fallbackUrl;
}
// Für andere Ports, verwende Standard-Backend-Port
const defaultPort = currentProtocol === 'https:' ? '8443' : '5000';
const fallbackUrl = `${currentProtocol}//${currentHost}:${defaultPort}`;
console.log('🔄 Admin Standard-Fallback:', fallbackUrl);
// Für alle anderen Fälle, verwende HTTPS auf Port 443
const fallbackUrl = `https://${currentHost}`;
console.log('🔄 Admin Fallback zu HTTPS:443:', fallbackUrl);
return fallbackUrl;
}

30
backend/myp.service Normal file
View File

@ -0,0 +1,30 @@
[Unit]
Description=MYP Reservation Platform Backend
After=network.target
Wants=network.target
[Service]
Type=simple
User=user
Group=user
WorkingDirectory=/home/user/Projektarbeit-MYP/backend/app
Environment=PYTHONPATH=/home/user/Projektarbeit-MYP/backend/app
Environment=FLASK_ENV=production
Environment=FLASK_APP=app.py
ExecStart=/home/user/Projektarbeit-MYP/backend/venv/bin/python3 app.py --host 0.0.0.0 --port 443 --cert certs/backend.crt --key certs/backend.key
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=myp-backend
# Security settings
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/home/user/Projektarbeit-MYP/backend/app/logs
ReadWritePaths=/home/user/Projektarbeit-MYP/backend/app/database
[Install]
WantedBy=multi-user.target

View File

@ -1,96 +0,0 @@
version: '3'
services:
# Backend (Flask) auf Port 443 mit SSL
backend:
build:
context: ./backend
dockerfile: Dockerfile
container_name: myp-backend
restart: unless-stopped
hostname: raspberrypi
ports:
- "80:80" # HTTP Fallback
- "443:443" # HTTPS
volumes:
- ./backend:/app
- ./backend/logs:/app/logs
- ./backend/instance:/app/instance
networks:
- myp-network
environment:
- FLASK_APP=app/app.py
- FLASK_ENV=production
- SSL_ENABLED=true
- SSL_HOSTNAME=raspberrypi
command: python -m app.app --dual-protocol
healthcheck:
test: ["CMD", "curl", "-k", "https://localhost:443/health || curl http://localhost:80/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# Next.js Frontend
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
container_name: myp-rp
restart: unless-stopped
environment:
- NODE_ENV=production
- NEXT_PUBLIC_API_URL=https://raspberrypi:443
- NEXT_PUBLIC_BACKEND_HOST=raspberrypi:443
volumes:
- ./frontend:/app
- /app/node_modules
- /app/.next
ports:
- "3000:3000"
networks:
- myp-network
healthcheck:
test: ["CMD", "wget", "--spider", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# Caddy Proxy für Frontend auf Port 443 mit SSL
caddy:
image: caddy:2.7-alpine
container_name: myp-caddy
restart: unless-stopped
hostname: m040tbaraspi001
ports:
- "80:80"
- "443:443"
volumes:
- ./frontend/docker/caddy/Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
- ./backend/instance/ssl:/etc/caddy/ssl
networks:
- myp-network
extra_hosts:
- "host.docker.internal:host-gateway"
- "raspberrypi:backend"
- "m040tbaraspi001.de040.corpintra.net:127.0.0.1"
environment:
- CADDY_HOST=m040tbaraspi001.de040.corpintra.net
- CADDY_DOMAIN=m040tbaraspi001.de040.corpintra.net
cap_add:
- NET_ADMIN
depends_on:
- backend
- frontend
networks:
myp-network:
driver: bridge
volumes:
caddy_data:
caddy_config:
backend_ssl:

View File

@ -1,95 +0,0 @@
version: '3'
services:
# Backend (Flask) auf Port 443 mit SSL
backend:
build:
context: ./backend
dockerfile: Dockerfile
container_name: myp-backend
restart: unless-stopped
hostname: raspberrypi
ports:
- "80:80" # HTTP Fallback
- "443:443" # HTTPS
volumes:
- ./backend:/app
- ./backend/logs:/app/logs
- ./backend/instance:/app/instance
networks:
- myp-network
environment:
- FLASK_APP=app/app.py
- FLASK_ENV=production
- SSL_ENABLED=true
- SSL_HOSTNAME=raspberrypi
healthcheck:
test: ["CMD", "curl", "-k", "https://localhost:443/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# Next.js Frontend
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
container_name: myp-rp
restart: unless-stopped
environment:
- NODE_ENV=production
- NEXT_PUBLIC_API_URL=https://raspberrypi:443
- NEXT_PUBLIC_BACKEND_HOST=raspberrypi:443
volumes:
- ./frontend:/app
- /app/node_modules
- /app/.next
ports:
- "3000:3000"
networks:
- myp-network
healthcheck:
test: ["CMD", "wget", "--spider", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# Caddy Proxy für Frontend auf Port 443 mit SSL
caddy:
image: caddy:2.7-alpine
container_name: myp-caddy
restart: unless-stopped
hostname: m040tbaraspi001
ports:
- "80:80"
- "443:443"
volumes:
- ./frontend/docker/caddy/Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
- ./backend/instance/ssl:/etc/caddy/ssl
networks:
- myp-network
extra_hosts:
- "host.docker.internal:host-gateway"
- "raspberrypi:backend"
- "m040tbaraspi001.de040.corpintra.net:127.0.0.1"
environment:
- CADDY_HOST=m040tbaraspi001.de040.corpintra.net
- CADDY_DOMAIN=m040tbaraspi001.de040.corpintra.net
cap_add:
- NET_ADMIN
depends_on:
- backend
- frontend
networks:
myp-network:
driver: bridge
volumes:
caddy_data:
caddy_config:
backend_ssl:

191
docs/README.md Normal file
View File

@ -0,0 +1,191 @@
# MYP Reservation Platform
Mercedes-Benz Werk 040 Berlin - 3D-Drucker Reservierungsplattform
## 🚀 Schnellstart
### Voraussetzungen
- **Backend (Raspberry Pi)**: Python 3.11, systemd
- **Frontend (m040tbaraspi001)**: Docker, Docker Compose
### Installation
#### Backend Installation (Raspberry Pi)
```bash
# Repository klonen
git clone <repository-url>
cd Projektarbeit-MYP
# Backend installieren
./install.sh backend
```
#### Frontend Installation (m040tbaraspi001)
```bash
# Repository klonen
git clone <repository-url>
cd Projektarbeit-MYP
# Frontend installieren
./install.sh frontend
```
### Services starten
#### Backend
```bash
sudo systemctl start myp.service
sudo systemctl status myp.service
```
#### Frontend
```bash
cd frontend
docker-compose up -d
docker-compose logs -f
```
## 🌐 Zugriff
- **Frontend**: https://m040tbaraspi001.de040.corpintra.net
- **Backend API**: https://raspberrypi/api
## 🔧 Konfiguration
### Netzwerk
| Komponente | Hostname | IP | Port |
|------------|----------|----|----- |
| Frontend | m040tbaraspi001.de040.corpintra.net | 192.168.0.109 | 443 |
| Backend | raspberrypi | 192.168.0.105 | 443 |
### TLS-Zertifikate
Selbstsignierte Zertifikate werden automatisch generiert:
- Backend: `backend/app/certs/`
- Frontend: `frontend/certs/`
## 📊 Health Checks
```bash
# Backend
curl -k https://raspberrypi/api/test
# Frontend
curl -k https://m040tbaraspi001.de040.corpintra.net/health
```
## 🛠️ Entwicklung
### Backend Debug-Modus
```bash
cd backend/app
python3.11 app.py --debug
```
### Frontend Development
```bash
cd frontend
npm run dev
```
## 📁 Projektstruktur
```
Projektarbeit-MYP/
├── backend/
│ ├── app/
│ │ ├── certs/ # TLS-Zertifikate
│ │ ├── database/ # SQLite-Datenbank
│ │ ├── logs/ # Anwendungslogs
│ │ └── app.py # Hauptanwendung
│ ├── myp.service # systemd Service
│ └── requirements.txt # Python-Abhängigkeiten
├── frontend/
│ ├── certs/ # TLS-Zertifikate
│ ├── docker/
│ │ └── caddy/
│ │ └── Caddyfile # Reverse Proxy Konfiguration
│ ├── src/ # Next.js Anwendung
│ └── docker-compose.yml
├── docs/ # Dokumentation
├── scripts/ # Hilfsskripte
└── install.sh # Zentraler Installer
```
## 🔒 Sicherheit
- HTTPS-only (Port 443)
- Selbstsignierte TLS-Zertifikate
- HTTP → HTTPS Redirect
- Security Headers (HSTS, CSP, etc.)
## 📝 Logs
### Backend
```bash
# systemd Journal
sudo journalctl -u myp.service -f
# Anwendungslogs
tail -f backend/app/logs/app/app.log
```
### Frontend
```bash
# Docker Logs
docker-compose logs -f
# Caddy Logs
docker-compose logs caddy
```
## 🆘 Troubleshooting
### Backend startet nicht
```bash
# Service Status prüfen
sudo systemctl status myp.service
# Logs prüfen
sudo journalctl -u myp.service --no-pager
# Zertifikate prüfen
ls -la backend/app/certs/
```
### Frontend nicht erreichbar
```bash
# Container Status prüfen
docker-compose ps
# Netzwerk prüfen
docker network ls
# Zertifikate prüfen
ls -la frontend/certs/
```
### Verbindungsprobleme
```bash
# DNS auflösen
nslookup raspberrypi
nslookup m040tbaraspi001.de040.corpintra.net
# Ports prüfen
netstat -tlnp | grep :443
```
## 📋 Version
- **Version**: 3.2-final
- **Build**: Production
- **Datum**: $(date)
## 👥 Support
Bei Problemen wenden Sie sich an das IT-Team des Mercedes-Benz Werk 040 Berlin.

View File

@ -1,32 +0,0 @@
# MYP - Manage Your Printer
MYP (Manage Your Printer) ist eine Webanwendung zur Reservierung von 3D-Druckern.
Sie wurde im Rahmen des Abschlussprojektes der Fachinformatiker Ausbildung für Daten- und Prozessanalyse für die Technische Berufsausbildung des Mercedes-Benz Werkes Berlin-Marienfelde entwickelt.
## Deployment
### Voraussetzungen
- Netzwerk auf Raspberry Pi ist eingerichtet
- Docker ist installiert
### Schritte
1. Docker-Container bauen (docker/build.sh)
2. Docker-Container speichern (docker/save.sh caddy:2.8 myp-rp:latest)
3. Docker-Container auf Raspberry Pi bereitstellen (docker/deploy.sh)
## Entwicklerinformationen
### Raspberry Pi Einstellungen
Auf dem Raspberry Pi wurde Raspbian Lite installiert.
Unter /srv/* sind die Projektdateien zu finden.
### Anmeldedaten
```
Benutzer: myp
Passwort: (persönlich bekannt)
```

View File

@ -1,286 +0,0 @@
#!/usr/bin/env node
/**
* Dieses Skript konfiguriert das Next.js-Frontend, um das selbstsignierte SSL-Zertifikat zu akzeptieren
* und die richtigen SSL-Einstellungen im Frontend zu setzen.
*/
const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
// Pfade definieren
const ENV_LOCAL_PATH = path.join(__dirname, '.env.local');
const ENV_FRONTEND_PATH = path.join(__dirname, 'env.frontend');
const SSL_DIR = path.join(__dirname, 'ssl');
const NEXT_CONFIG_PATH = path.join(__dirname, 'next.config.js');
console.log('=== Frontend-SSL-Konfiguration ===');
// Verzeichnis erstellen, falls es nicht existiert
if (!fs.existsSync(SSL_DIR)) {
console.log(`SSL-Verzeichnis wird erstellt: ${SSL_DIR}`);
fs.mkdirSync(SSL_DIR, { recursive: true });
}
// Prüfen, ob SSL-Zertifikate existieren
if (!fs.existsSync(path.join(SSL_DIR, 'myp.crt')) || !fs.existsSync(path.join(SSL_DIR, 'myp.key'))) {
console.log('SSL-Zertifikate nicht gefunden. Prüfe Backend-Verzeichnis...');
// Versuche, die Zertifikate aus dem Backend zu kopieren
const backendCertPath = path.join('/home/user/Projektarbeit-MYP/backend/certs/myp.crt');
const backendKeyPath = path.join('/home/user/Projektarbeit-MYP/backend/certs/myp.key');
if (fs.existsSync(backendCertPath) && fs.existsSync(backendKeyPath)) {
console.log('Zertifikate im Backend-Verzeichnis gefunden. Kopiere...');
fs.copyFileSync(backendCertPath, path.join(SSL_DIR, 'myp.crt'));
fs.copyFileSync(backendKeyPath, path.join(SSL_DIR, 'myp.key'));
console.log('Zertifikate erfolgreich in das Frontend-Verzeichnis kopiert.');
} else {
console.error('SSL-Zertifikate nicht gefunden. Bitte zuerst das Backend-Skript ausführen.');
process.exit(1);
}
}
console.log('SSL-Zertifikate gefunden. Konfiguriere Frontend...');
// Umgebungsvariablen konfigurieren
function updateEnvFile() {
try {
let envContent;
// .env.local erstellen oder aktualisieren
if (fs.existsSync(ENV_LOCAL_PATH)) {
envContent = fs.readFileSync(ENV_LOCAL_PATH, 'utf8');
} else if (fs.existsSync(ENV_FRONTEND_PATH)) {
envContent = fs.readFileSync(ENV_FRONTEND_PATH, 'utf8');
} else {
envContent = `# MYP Frontend Umgebungsvariablen\n`;
}
// SSL-Konfigurationen mit alternativen Testoptionen
const sslConfigs = [
'NODE_TLS_REJECT_UNAUTHORIZED=0',
'HTTPS=true',
'SSL_CRT_FILE=./ssl/myp.crt',
'SSL_KEY_FILE=./ssl/myp.key',
'NEXT_PUBLIC_API_URL=https://raspberrypi:443',
'NEXT_PUBLIC_BACKEND_HOST=raspberrypi:443',
'NEXT_PUBLIC_BACKEND_PROTOCOL=https',
// Alternative Konfigurationen für Testversuche (auskommentiert)
'# Alternative ohne HTTPS',
'# HTTPS=false',
'# NEXT_PUBLIC_API_URL=http://raspberrypi:80',
'# NEXT_PUBLIC_BACKEND_HOST=raspberrypi:80',
'# NEXT_PUBLIC_BACKEND_PROTOCOL=http',
'# Alternative mit IP statt Hostname',
'# NEXT_PUBLIC_API_URL=https://192.168.0.105:443',
'# NEXT_PUBLIC_BACKEND_HOST=192.168.0.105:443',
'# Alternative mit localhost',
'# NEXT_PUBLIC_API_URL=https://192.168.0.105:5000',
'# NEXT_PUBLIC_BACKEND_HOST=192.168.0.105:5000',
'# Alternative Ports testen',
'# NEXT_PUBLIC_API_URL=https://raspberrypi:8443',
'# NEXT_PUBLIC_BACKEND_HOST=raspberrypi:8443',
'# NEXT_PUBLIC_API_URL=http://raspberrypi:8080',
'# NEXT_PUBLIC_BACKEND_HOST=raspberrypi:8080'
];
// Existierende Konfigurationen aktualisieren
sslConfigs.forEach(config => {
const [key, value] = config.split('=');
const regex = new RegExp(`^${key}=.*$`, 'm');
if (envContent.match(regex)) {
// Update existierende Konfiguration
envContent = envContent.replace(regex, config);
} else {
// Neue Konfiguration hinzufügen
envContent += `\n${config}`;
}
});
// Speichern der aktualisierten Umgebungsvariablen
fs.writeFileSync(ENV_LOCAL_PATH, envContent);
console.log('.env.local Datei aktualisiert mit SSL-Konfigurationen');
return true;
} catch (error) {
console.error(`Fehler bei der Aktualisierung der Umgebungsvariablen: ${error.message}`);
return false;
}
}
// Next.js-Konfiguration aktualisieren
function updateNextConfig() {
try {
let configContent;
// next.config.js erstellen oder aktualisieren
if (fs.existsSync(NEXT_CONFIG_PATH)) {
configContent = fs.readFileSync(NEXT_CONFIG_PATH, 'utf8');
} else {
configContent = `/** @type {import('next').NextConfig} */\n\nconst nextConfig = {}\n\nmodule.exports = nextConfig\n`;
}
// Prüfen, ob bereits eine HTTPS-Konfiguration vorhanden ist
if (configContent.includes('serverOptions:') && configContent.includes('https:')) {
console.log('HTTPS-Konfiguration ist bereits in der next.config.js vorhanden.');
return true;
}
// HTTPS-Konfiguration hinzufügen
const httpsConfig = `
/** @type {import('next').NextConfig} */
const fs = require('fs');
const path = require('path');
const nextConfig = {
reactStrictMode: true,
webpack: (config) => {
return config;
},
// HTTPS-Konfiguration für die Entwicklung
devServer: {
https: {
key: fs.readFileSync(path.resolve(__dirname, 'ssl/myp.key')),
cert: fs.readFileSync(path.resolve(__dirname, 'ssl/myp.crt')),
},
},
// Konfiguration für selbstsignierte Zertifikate
serverOptions: {
https: {
key: fs.readFileSync(path.resolve(__dirname, 'ssl/myp.key')),
cert: fs.readFileSync(path.resolve(__dirname, 'ssl/myp.crt')),
},
},
// Zusätzliche Konfigurationen
async rewrites() {
return [
{
source: '/api/:path*',
destination: 'https://raspberrypi:443/api/:path*',
},
]
}
};
module.exports = nextConfig;
`;
// Speichern der aktualisierten Next.js-Konfiguration
fs.writeFileSync(NEXT_CONFIG_PATH, httpsConfig);
console.log('next.config.js Datei aktualisiert mit HTTPS-Konfiguration');
return true;
} catch (error) {
console.error(`Fehler bei der Aktualisierung der Next.js-Konfiguration: ${error.message}`);
return false;
}
}
// Update der Fetch-Konfiguration
function updateFetchConfig() {
try {
const fetchConfigPath = path.join(__dirname, 'src', 'utils', 'api-config.ts');
if (!fs.existsSync(fetchConfigPath)) {
console.warn('Datei api-config.ts nicht gefunden. Überspringe Aktualisierung.');
return true;
}
// Lesen der aktuellen Konfiguration
let configContent = fs.readFileSync(fetchConfigPath, 'utf8');
// Sicherstellen, dass SSL-Verbindungen akzeptiert werden
if (!configContent.includes('NODE_TLS_REJECT_UNAUTHORIZED=0')) {
// Hinzufügen eines Kommentars zu Beginn der Datei
configContent = `// SSL-Verbindungen akzeptieren (selbstsignierte Zertifikate)
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
${configContent}`;
}
// Speichern der aktualisierten Fetch-Konfiguration
fs.writeFileSync(fetchConfigPath, configContent);
console.log('api-config.ts Datei aktualisiert, um selbstsignierte Zertifikate zu akzeptieren');
return true;
} catch (error) {
console.error(`Fehler bei der Aktualisierung der Fetch-Konfiguration: ${error.message}`);
return false;
}
}
// Abhängigkeiten installieren
function installDependencies() {
try {
console.log('Installiere benötigte Abhängigkeiten...');
execSync('npm install --save-dev https-localhost', { stdio: 'inherit' });
console.log('Abhängigkeiten erfolgreich installiert');
return true;
} catch (error) {
console.error(`Fehler bei der Installation der Abhängigkeiten: ${error.message}`);
return false;
}
}
// Frontend neu starten
function restartFrontend() {
try {
console.log('Starte Frontend-Server neu...');
// Prüfen, ob wir uns in Docker befinden
if (process.env.CONTAINER) {
console.log('Docker-Umgebung erkannt, verwende Docker-Befehle...');
execSync('docker-compose restart frontend', { stdio: 'inherit' });
} else {
console.log('Lokale Umgebung, starte Next.js-Entwicklungsserver neu...');
// Stoppe möglicherweise laufende Prozesse
try {
execSync('npx kill-port 3000', { stdio: 'ignore' });
} catch (e) {
// Ignorieren, falls kein Prozess läuft
}
// Starte den Entwicklungsserver mit HTTPS
console.log('Frontend wird mit HTTPS gestartet. Verwende https://localhost:3000 zum Zugriff.');
console.log('Das Frontend wird im Hintergrund gestartet. Verwenden Sie "npm run dev", um es manuell zu starten.');
}
console.log('Frontend-Server erfolgreich konfiguriert.');
return true;
} catch (error) {
console.error(`Fehler beim Neustart des Frontend-Servers: ${error.message}`);
return false;
}
}
// Hauptfunktion
async function main() {
let success = true;
success = updateEnvFile() && success;
success = updateNextConfig() && success;
success = updateFetchConfig() && success;
success = installDependencies() && success;
success = restartFrontend() && success;
if (success) {
console.log('\n=== Konfiguration erfolgreich abgeschlossen ===');
console.log('Das Frontend wurde für die Verwendung von HTTPS mit dem selbstsignierten Zertifikat konfiguriert.');
console.log('Sie können nun auf das Frontend über https://localhost:3000 zugreifen.');
console.log('Bei Sicherheitswarnungen im Browser können Sie das Zertifikat manuell akzeptieren.');
} else {
console.error('\n=== Konfiguration nicht vollständig abgeschlossen ===');
console.error('Es gab Probleme bei der Konfiguration des Frontends.');
console.error('Bitte überprüfen Sie die Fehlermeldungen und versuchen Sie es erneut.');
}
}
// Ausführen der Hauptfunktion
main().catch(error => {
console.error(`Unerwarteter Fehler: ${error.message}`);
process.exit(1);
});

View File

@ -10,7 +10,7 @@ const PORT = process.env.PORT || 8081;
// Konfigurationsdatei
const CONFIG_FILE = path.join(__dirname, '../../../.env.local');
const DEFAULT_BACKEND_URL = 'http://192.168.0.105:5000';
const DEFAULT_BACKEND_URL = 'https://raspberrypi';
// Middleware
app.use(express.json());

View File

@ -1,62 +0,0 @@
version: '3'
services:
# Next.js Frontend
frontend:
build:
context: .
dockerfile: Dockerfile
container_name: myp-frontend
restart: unless-stopped
environment:
- NODE_ENV=production
- NEXT_PUBLIC_API_URL=https://raspberrypi:443
- NEXT_PUBLIC_BACKEND_HOST=raspberrypi:443
- PORT=80
volumes:
- ./certs:/app/certs
ports:
- "80"
networks:
- myp-network
healthcheck:
test: ["CMD", "wget", "--spider", "http://localhost:80/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# Caddy Proxy für SSL-Terminierung
caddy:
image: caddy:2.7-alpine
container_name: myp-caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./docker/caddy/Caddyfile:/etc/caddy/Caddyfile
- ./certs:/etc/caddy/certs
- caddy_data:/data
- caddy_config:/config
networks:
- myp-network
depends_on:
- frontend
extra_hosts:
- "host.docker.internal:host-gateway"
- "raspberrypi:192.168.0.105"
- "m040tbaraspi001.de040.corpintra.net:127.0.0.1"
environment:
- CADDY_HOST=m040tbaraspi001.de040.corpintra.net
- CADDY_DOMAIN=m040tbaraspi001.de040.corpintra.net
cap_add:
- NET_ADMIN
networks:
myp-network:
driver: bridge
volumes:
caddy_data:
caddy_config:

View File

@ -1,5 +1,5 @@
# 🎨 MYP Frontend - Entwicklungsumgebung Konfiguration
# Frontend-Service für die Entwicklung mit Raspberry Pi Backend
# 🎨 MYP Frontend - Produktionsumgebung Konfiguration
# Frontend-Service für die Produktion mit Raspberry Pi Backend
version: '3.8'
@ -8,152 +8,64 @@ services:
frontend:
build:
context: .
dockerfile: Dockerfile.dev
args:
- BUILDKIT_INLINE_CACHE=1
- NODE_ENV=development
image: myp/frontend:dev
container_name: myp-frontend-dev
dockerfile: Dockerfile
container_name: myp-frontend
restart: unless-stopped
environment:
- NODE_ENV=development
- NEXT_TELEMETRY_DISABLED=1
# Backend API Konfiguration (Raspberry Pi)
- NEXT_PUBLIC_API_URL=http://192.168.0.105:5000
- NEXT_PUBLIC_BACKEND_HOST=192.168.0.105:5000
# Frontend Server
- PORT=3000
- HOSTNAME=0.0.0.0
# Auth Konfiguration (Entwicklung)
- NEXTAUTH_URL=http://localhost:3000
- NEXTAUTH_SECRET=dev-frontend-auth-secret
# Debug-Einstellungen
- DEBUG=true
- NEXT_DEBUG=true
- NODE_ENV=production
- NEXT_PUBLIC_API_URL=https://raspberrypi
- NEXT_PUBLIC_BACKEND_HOST=raspberrypi
- NEXT_PUBLIC_FRONTEND_URL=https://m040tbaraspi001.de040.corpintra.net
- NEXTAUTH_URL=https://m040tbaraspi001.de040.corpintra.net
- NEXTAUTH_SECRET=${NEXTAUTH_SECRET:-myp-secret-key-2024}
- GITHUB_CLIENT_ID=${GITHUB_CLIENT_ID}
- GITHUB_CLIENT_SECRET=${GITHUB_CLIENT_SECRET}
- NEXT_PUBLIC_OAUTH_CALLBACK_URL=https://m040tbaraspi001.de040.corpintra.net/auth/login/callback
volumes:
- .:/app
- /app/node_modules
- /app/.next
- ./public:/app/public:ro
- ./certs:/app/certs
ports:
- "3000:3000" # Direkter Port-Zugang für Frontend-Server
networks:
- frontend-network
extra_hosts:
- "raspberrypi:192.168.0.105"
- myp-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
labels:
- "service.type=frontend"
- "service.name=myp-frontend-dev"
- "service.environment=development"
# === FRONTEND CACHE (Optional: Redis für Session Management) ===
frontend-cache:
image: redis:7.2-alpine
container_name: myp-frontend-cache
# === CADDY PROXY ===
caddy:
image: caddy:2-alpine
container_name: myp-caddy
restart: unless-stopped
command: redis-server --appendonly yes --requirepass ${FRONTEND_REDIS_PASSWORD:-frontend_cache_password}
volumes:
- frontend_redis_data:/data
ports:
- "6380:6379" # Separater Port vom Backend-Cache
networks:
- frontend-network
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
# === FRONTEND CDN/NGINX (Statische Assets) ===
frontend-cdn:
image: nginx:alpine
container_name: myp-frontend-cdn
restart: unless-stopped
- "80:80"
- "443:443"
volumes:
- ./public:/usr/share/nginx/html/static:ro
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- frontend_cdn_cache:/var/cache/nginx
ports:
- "8080:80" # Separater Port für statische Assets
- ./docker/caddy/Caddyfile:/etc/caddy/Caddyfile
- ./certs:/etc/ssl/certs/myp
- caddy_data:/data
- caddy_config:/config
networks:
- frontend-network
- myp-network
depends_on:
- frontend
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 10s
retries: 3
labels:
- "service.type=cdn"
- "service.name=myp-frontend-cdn"
environment:
- CADDY_INGRESS_NETWORKS=myp-network
# === PERSISTENTE VOLUMES ===
volumes:
frontend_data:
caddy_data:
driver: local
frontend_cache:
driver: local
frontend_redis_data:
driver: local
frontend_cdn_cache:
caddy_config:
driver: local
# === FRONTEND-NETZWERK ===
# === NETZWERK ===
networks:
frontend-network:
myp-network:
driver: bridge
driver_opts:
com.docker.network.enable_ipv6: "false"
com.docker.network.bridge.enable_ip_masquerade: "true"
labels:
- "description=MYP Frontend Server Netzwerk"
- "description=MYP Production Network"
- "project=myp-frontend"
- "tier=frontend"
# === KONFIGURATION FÜR FRONTEND ===
x-frontend-defaults: &frontend-defaults
restart: unless-stopped
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
labels: "service,environment,tier"
x-healthcheck-frontend: &frontend-healthcheck
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
- "tier=production"

View File

@ -1,62 +0,0 @@
version: '3.8'
services:
# Next.js Frontend
frontend:
build:
context: .
dockerfile: Dockerfile
container_name: myp-frontend-prod
restart: unless-stopped
environment:
- NODE_ENV=production
- NEXT_PUBLIC_API_URL=https://raspberrypi:443
- NEXT_PUBLIC_BACKEND_HOST=raspberrypi:443
- PORT=80
volumes:
- ./certs:/app/certs
- frontend_data:/usr/src/app/db
networks:
- myp-network
healthcheck:
test: ["CMD", "wget", "--spider", "http://localhost:80/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# Caddy Proxy für SSL-Terminierung
caddy:
image: caddy:2.7-alpine
container_name: myp-caddy-prod
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./docker/caddy/Caddyfile:/etc/caddy/Caddyfile
- ./certs:/etc/caddy/certs
- caddy_data:/data
- caddy_config:/config
networks:
- myp-network
depends_on:
- frontend
extra_hosts:
- "host.docker.internal:host-gateway"
- "raspberrypi:192.168.0.105"
- "m040tbaraspi001.de040.corpintra.net:127.0.0.1"
environment:
- CADDY_HOST=m040tbaraspi001.de040.corpintra.net
- CADDY_DOMAIN=m040tbaraspi001.de040.corpintra.net
cap_add:
- NET_ADMIN
networks:
myp-network:
driver: bridge
volumes:
caddy_data:
caddy_config:
frontend_data:

View File

@ -1,62 +1,49 @@
version: '3'
version: '3.8'
services:
# Next.js Frontend
frontend:
frontend-app:
build:
context: .
dockerfile: Dockerfile
container_name: myp-frontend
restart: unless-stopped
container_name: myp-frontend-app
environment:
- NODE_ENV=production
- NEXT_PUBLIC_API_URL=https://raspberrypi:443
- NEXT_PUBLIC_BACKEND_HOST=raspberrypi:443
- PORT=80
volumes:
- ./certs:/app/certs
ports:
- "80"
- NEXT_PUBLIC_API_URL=https://raspberrypi
- HOSTNAME=m040tbaraspi001.de040.corpintra.net
networks:
- myp-network
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--spider", "http://localhost:80/health"]
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# Caddy Proxy für SSL-Terminierung
caddy:
image: caddy:2.7-alpine
image: caddy:2-alpine
container_name: myp-caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./docker/caddy/Caddyfile:/etc/caddy/Caddyfile
- ./certs:/etc/caddy/certs
- ./certs:/etc/ssl/certs/myp
- caddy_data:/data
- caddy_config:/config
networks:
- myp-network
depends_on:
- frontend
extra_hosts:
- "host.docker.internal:host-gateway"
- "raspberrypi:192.168.0.105"
- "m040tbaraspi001.de040.corpintra.net:127.0.0.1"
- frontend-app
restart: unless-stopped
environment:
- CADDY_HOST=m040tbaraspi001.de040.corpintra.net
- CADDY_DOMAIN=m040tbaraspi001.de040.corpintra.net
cap_add:
- NET_ADMIN
networks:
myp-network:
driver: bridge
- CADDY_INGRESS_NETWORKS=myp-network
volumes:
caddy_data:
caddy_config:
caddy_config:
networks:
myp-network:
driver: bridge

View File

@ -1,76 +1,36 @@
{
debug
auto_https off
local_certs
# HTTP to HTTPS redirect
:80 {
redir https://{host}{uri} permanent
}
# Produktionsumgebung - Frontend auf Port 80/443 mit selbstsigniertem Zertifikat
:80, :443 {
# TLS mit automatisch generierten selbstsignierten Zertifikaten
tls internal {
on_demand
}
# API Anfragen zum Backend (Raspberry Pi) weiterleiten
@api {
path /api/* /health
}
handle @api {
uri strip_prefix /api
reverse_proxy raspberrypi:443 {
transport http {
tls
tls_insecure_skip_verify
}
header_up Host {upstream_hostport}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}
# Alle anderen Anfragen zum Frontend weiterleiten (auf Port 80 intern)
handle {
reverse_proxy frontend:80 {
header_up Host {upstream_hostport}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}
# OAuth Callbacks
@oauth path /auth/login/callback*
handle @oauth {
header Cache-Control "no-cache"
reverse_proxy frontend:80
}
# HTTPS Frontend
m040tbaraspi001.de040.corpintra.net:443 {
# TLS configuration with custom certificates
tls /etc/ssl/certs/myp/frontend.crt /etc/ssl/certs/myp/frontend.key
# Produktions-Header
# Security headers
header {
# Enable HSTS
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
# XSS Protection
X-Content-Type-Options "nosniff"
X-Frame-Options "SAMEORIGIN"
Referrer-Policy "strict-origin-when-cross-origin"
X-Frame-Options "DENY"
X-XSS-Protection "1; mode=block"
# CSP
Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' https://raspberrypi;"
# Remove server header
-Server
}
}
# Spezifische Hostname-Konfiguration für Mercedes-Benz Werk 040 Berlin (falls benötigt)
m040tbaraspi001.de040.corpintra.net {
# TLS mit automatisch generierten selbstsignierten Zertifikaten
tls internal {
on_demand
# Health check endpoint
handle /health {
respond "OK" 200
}
# API Anfragen zum Backend (Raspberry Pi) weiterleiten
@api {
path /api/* /health
}
handle @api {
uri strip_prefix /api
reverse_proxy raspberrypi:443 {
# API proxy to backend
handle /api/* {
reverse_proxy https://raspberrypi {
transport http {
tls
tls_insecure_skip_verify
}
header_up Host {upstream_hostport}
@ -79,85 +39,27 @@ m040tbaraspi001.de040.corpintra.net {
header_up X-Forwarded-Proto {scheme}
}
}
# Alle anderen Anfragen zum Frontend weiterleiten
handle {
reverse_proxy frontend:80 {
header_up Host {upstream_hostport}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}
# OAuth Callbacks
@oauth path /auth/login/callback*
handle @oauth {
header Cache-Control "no-cache"
reverse_proxy frontend:80
# Frontend application
reverse_proxy frontend-app:3000 {
header_up Host {host}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
# Produktions-Header
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
X-Frame-Options "SAMEORIGIN"
Referrer-Policy "strict-origin-when-cross-origin"
# Logging
log {
output file /var/log/caddy/access.log
format json
}
# Enable compression
encode gzip
}
# Entwicklungsumgebung - Localhost und Raspberry Pi Backend (weiterhin für lokale Entwicklung verfügbar)
localhost, 127.0.0.1 {
# API Anfragen zum Raspberry Pi Backend weiterleiten
@api {
path /api/* /health
}
handle @api {
uri strip_prefix /api
reverse_proxy raspberrypi:443 {
transport http {
tls
tls_insecure_skip_verify
}
header_up Host {upstream_hostport}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}
# Alle anderen Anfragen zum Frontend weiterleiten
handle {
reverse_proxy myp-rp-dev:3000 {
header_up Host {upstream_hostport}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}
# TLS für lokale Entwicklung
tls /etc/caddy/ssl/frontend.crt /etc/caddy/ssl/frontend.key
# OAuth Callbacks für Entwicklung
@oauth path /auth/login/callback*
handle @oauth {
header Cache-Control "no-cache"
reverse_proxy myp-rp-dev:3000
}
# Entwicklungsfreundliche Header
header {
# Weniger restriktive Sicherheitsheader für Entwicklung
X-Content-Type-Options "nosniff"
X-Frame-Options "SAMEORIGIN"
# Keine Caches für Entwicklung
Cache-Control "no-store, no-cache, must-revalidate"
# CORS für Entwicklung
Access-Control-Allow-Origin "*"
Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Access-Control-Allow-Headers "Content-Type, Authorization"
}
}
# Fallback for direct IP access
192.168.0.109:443 {
tls /etc/ssl/certs/myp/frontend.crt /etc/ssl/certs/myp/frontend.key
redir https://m040tbaraspi001.de040.corpintra.net{uri} permanent
}

View File

@ -1,30 +0,0 @@
services:
caddy:
image: caddy:2.8
container_name: caddy
restart: unless-stopped
ports:
- 80:80
- 443:443
volumes:
- ./caddy/data:/data
- ./caddy/config:/config
- ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
myp-rp:
image: myp-rp:latest
container_name: myp-rp
environment:
- NEXT_PUBLIC_API_URL=http://192.168.0.105:5000
- OAUTH_CLIENT_ID=client_id
- OAUTH_CLIENT_SECRET=client_secret
env_file: "/srv/myp-env/github.env"
volumes:
- /srv/MYP-DB:/usr/src/app/db
restart: unless-stopped
# Füge Healthcheck hinzu für besseres Monitoring
healthcheck:
test: ["CMD", "wget", "--spider", "http://localhost:3000"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ import { NextRequest, NextResponse } from 'next/server';
export async function GET(request: NextRequest) {
try {
// Prüfe Backend-Verbindung
const backendUrl = process.env.NEXT_PUBLIC_API_URL || 'http://192.168.0.105:5000';
const backendUrl = process.env.NEXT_PUBLIC_API_URL || 'https://raspberrypi';
let backendStatus = 'unknown';
try {

View File

@ -16,31 +16,16 @@ const getApiBaseUrl = () => {
// Verbindungsoptionen in Prioritätsreihenfolge
return {
primary: `https://${hostname}:443`,
primary: `https://${hostname}`,
fallbacks: [
`http://${hostname}:443`,
`https://${hostname}:80`,
`http://${hostname}:80`,
`https://${hostname}:5000`,
`http://${hostname}:5000`,
`https://raspberrypi:443`,
`http://raspberrypi:443`,
`https://raspberrypi:80`,
`http://raspberrypi:80`,
`https://raspberrypi:5000`,
`http://raspberrypi:5000`,
`https://192.168.0.105:443`,
`http://192.168.0.105:443`,
`https://192.168.0.105:80`,
`http://192.168.0.105:80`,
`https://192.168.0.105:5000`,
`http://192.168.0.105:5000`,
`https://raspberrypi`,
`https://192.168.0.105`,
]
};
}
// Standardwert für serverseitiges Rendering
return `https://raspberrypi:443`;
return `https://raspberrypi`;
};
export const API_BASE_URL = getApiBaseUrl();
@ -63,8 +48,8 @@ const getFrontendUrl = () => {
}
}
// Priorität 3: Default für Localhost
return "https://localhost:3000";
// Priorität 3: Default für Localhost (development)
return "https://m040tbaraspi001.de040.corpintra.net";
};
export const FRONTEND_URL = getFrontendUrl();

View File

@ -1,179 +0,0 @@
#!/usr/bin/env node
/**
* Hilfsskript zur Aktualisierung der OAuth-Konfiguration im MYP-Frontend
*
* Dieses Skript wird automatisch beim Build ausgeführt, um sicherzustellen,
* dass die OAuth-Konfiguration korrekt ist.
*/
const fs = require('fs');
const path = require('path');
// Pfad zur OAuth-Konfiguration und Routes
const callbackRoutePath = path.join(__dirname, 'src/app/auth/login/callback/route.ts');
const loginRoutePath = path.join(__dirname, 'src/app/auth/login/route.ts');
const oauthConfigPath = path.join(__dirname, 'src/server/auth/oauth.ts');
// Aktualisiere die OAuth-Konfiguration
try {
// 1. Prüfe, ob wir die USED_CALLBACK_URL exportieren müssen
let oauthContent = fs.readFileSync(oauthConfigPath, 'utf8');
if (!oauthContent.includes('export const USED_CALLBACK_URL')) {
console.log('✅ Aktualisiere OAuth-Konfiguration...');
// Füge die USED_CALLBACK_URL-Export hinzu
oauthContent = oauthContent.replace(
'// Erstelle GitHub OAuth-Client mit expliziter Redirect-URI',
'// Berechne die Callback-URL\nexport const USED_CALLBACK_URL = getCallbackUrl();\n\n// Erstelle GitHub OAuth-Client mit expliziter Redirect-URI'
);
// Schreibe die aktualisierte Datei
fs.writeFileSync(oauthConfigPath, oauthContent, 'utf8');
console.log('✅ OAuth-Konfiguration erfolgreich aktualisiert.');
} else {
console.log(' OAuth-Konfiguration ist bereits aktuell.');
}
} catch (error) {
console.error('❌ Fehler beim Aktualisieren der OAuth-Konfiguration:', error);
}
// Aktualisiere die OAuth-Callback-Route
try {
let callbackContent = fs.readFileSync(callbackRoutePath, 'utf8');
// Prüfe, ob Änderungen nötig sind
const needsUpdate =
callbackContent.includes('await github.validateAuthorizationCode(code, OAUTH_CALLBACK_URL)') ||
!callbackContent.includes('USED_CALLBACK_URL');
if (needsUpdate) {
console.log('✅ Aktualisiere OAuth-Callback-Route...');
// 1. Aktualisiere den Import
if (!callbackContent.includes('USED_CALLBACK_URL')) {
callbackContent = callbackContent.replace(
'import { type GitHubUserResult, github, isValidCallbackHost } from "@/server/auth/oauth";',
'import { type GitHubUserResult, github, isValidCallbackHost, USED_CALLBACK_URL } from "@/server/auth/oauth";'
);
// Entferne den OAUTH_CALLBACK_URL-Import, wenn er nicht mehr benötigt wird
if (callbackContent.includes('OAUTH_CALLBACK_URL')) {
callbackContent = callbackContent.replace(
', OAUTH_CALLBACK_URL } from "@/utils/api-config"',
' } from "@/utils/api-config"'
);
}
}
// 2. Korrigiere die validateAuthorizationCode-Funktion
if (callbackContent.includes('await github.validateAuthorizationCode(code, OAUTH_CALLBACK_URL)')) {
callbackContent = callbackContent.replace(
'await github.validateAuthorizationCode(code, OAUTH_CALLBACK_URL)',
'await github.validateAuthorizationCode(code)'
);
}
// 3. Aktualisiere die Logging-Nachricht
if (callbackContent.includes('console.log(`GitHub OAuth Token-Validierung mit Callback-URL: ${OAUTH_CALLBACK_URL}`)')) {
callbackContent = callbackContent.replace(
'console.log(`GitHub OAuth Token-Validierung mit Callback-URL: ${OAUTH_CALLBACK_URL}`)',
'console.log(`GitHub OAuth Token-Validierung erfolgreich, verwendete Callback-URL: ${USED_CALLBACK_URL}`)'
);
} else if (callbackContent.includes('console.log("GitHub OAuth Token-Validierung erfolgreich")')) {
callbackContent = callbackContent.replace(
'console.log("GitHub OAuth Token-Validierung erfolgreich")',
'console.log(`GitHub OAuth Token-Validierung erfolgreich, verwendete Callback-URL: ${USED_CALLBACK_URL}`)'
);
}
// Schreibe die aktualisierte Datei
fs.writeFileSync(callbackRoutePath, callbackContent, 'utf8');
console.log('✅ OAuth-Callback-Route erfolgreich aktualisiert.');
} else {
console.log(' OAuth-Callback-Route ist bereits aktuell.');
}
} catch (error) {
console.error('❌ Fehler beim Aktualisieren der OAuth-Callback-Route:', error);
}
// Package.json aktualisieren, um das Skript vor dem Build auszuführen
try {
const packageJsonPath = path.join(__dirname, 'package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
// Prüfe, ob das Skript bereits in den Build-Prozess integriert ist
if (packageJson.scripts.build === 'next build') {
console.log('✅ Aktualisiere package.json...');
// Füge das Skript zum Build-Prozess hinzu
packageJson.scripts.build = 'node update-package.js && next build';
// Schreibe die aktualisierte package.json
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf8');
console.log('✅ package.json erfolgreich aktualisiert.');
} else {
console.log(' package.json ist bereits aktualisiert.');
}
} catch (error) {
console.error('❌ Fehler beim Aktualisieren der package.json:', error);
}
// Aktualisiere die Login-Route
try {
let loginContent = fs.readFileSync(loginRoutePath, 'utf8');
// Prüfe, ob Änderungen nötig sind
const loginNeedsUpdate =
loginContent.includes('redirectURI: OAUTH_CALLBACK_URL') ||
!loginContent.includes('USED_CALLBACK_URL');
if (loginNeedsUpdate) {
console.log('✅ Aktualisiere OAuth-Login-Route...');
// 1. Aktualisiere den Import
if (!loginContent.includes('USED_CALLBACK_URL')) {
if (loginContent.includes('import { github } from "@/server/auth/oauth";')) {
loginContent = loginContent.replace(
'import { github } from "@/server/auth/oauth";',
'import { github, USED_CALLBACK_URL } from "@/server/auth/oauth";'
);
}
// Entferne den OAUTH_CALLBACK_URL-Import
if (loginContent.includes('import { OAUTH_CALLBACK_URL } from "@/utils/api-config";')) {
loginContent = loginContent.replace(
'import { OAUTH_CALLBACK_URL } from "@/utils/api-config";',
''
);
}
}
// 2. Korrigiere die createAuthorizationURL-Funktion
if (loginContent.includes('redirectURI: OAUTH_CALLBACK_URL')) {
loginContent = loginContent.replace(
/const url = await github\.createAuthorizationURL\(state, \{\s*scopes: \["user"\],\s*redirectURI: OAUTH_CALLBACK_URL,\s*\}\);/s,
'const url = await github.createAuthorizationURL(state, {\n\t\tscopes: ["user"],\n\t});'
);
}
// 3. Aktualisiere die Logging-Nachricht
if (loginContent.includes('console.log(`Verwendete Callback-URL: ${OAUTH_CALLBACK_URL}`')) {
loginContent = loginContent.replace(
'console.log(`Verwendete Callback-URL: ${OAUTH_CALLBACK_URL}`',
'console.log(`Verwendete Callback-URL: ${USED_CALLBACK_URL}`'
);
}
// Schreibe die aktualisierte Datei
fs.writeFileSync(loginRoutePath, loginContent, 'utf8');
console.log('✅ OAuth-Login-Route erfolgreich aktualisiert.');
} else {
console.log(' OAuth-Login-Route ist bereits aktuell.');
}
} catch (error) {
console.error('❌ Fehler beim Aktualisieren der OAuth-Login-Route:', error);
}
console.log('✅ OAuth-Konfiguration wurde erfolgreich vorbereitet.');

218
install.sh Executable file
View File

@ -0,0 +1,218 @@
#!/bin/bash
# MYP Reservation Platform - Zentraler Installer
# Unterstützt Backend und Frontend Installation
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$SCRIPT_DIR"
# 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
# Logging
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Hilfsfunktionen
check_root() {
if [[ $EUID -eq 0 ]]; then
log_error "Dieses Skript sollte nicht als root ausgeführt werden!"
exit 1
fi
}
check_dependencies() {
local deps=("python3.11" "curl" "openssl")
for dep in "${deps[@]}"; do
if ! command -v "$dep" &> /dev/null; then
log_error "Abhängigkeit '$dep' nicht gefunden!"
exit 1
fi
done
}
install_backend() {
log_info "=== Backend Installation ==="
cd "$PROJECT_ROOT/backend"
# Python Virtual Environment erstellen
log_info "Erstelle Python Virtual Environment..."
python3.11 -m venv venv
source venv/bin/activate
# Requirements installieren
log_info "Installiere Python-Abhängigkeiten..."
pip install --upgrade pip
pip install -r requirements.txt
# Zertifikate kopieren
log_info "Kopiere TLS-Zertifikate..."
mkdir -p app/certs
cp "$PROJECT_ROOT/backend/app/certs/backend.crt" app/certs/
cp "$PROJECT_ROOT/backend/app/certs/backend.key" app/certs/
chmod 600 app/certs/backend.key
chmod 644 app/certs/backend.crt
# Systemd Service installieren
log_info "Installiere systemd Service..."
sudo cp myp.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable myp.service
# Datenbank initialisieren
log_info "Initialisiere Datenbank..."
cd app
python3.11 init_db.py
log_success "Backend Installation abgeschlossen!"
log_info "Service starten mit: sudo systemctl start myp.service"
}
install_frontend() {
log_info "=== Frontend Installation ==="
cd "$PROJECT_ROOT/frontend"
# Docker prüfen
if ! command -v docker &> /dev/null; then
log_error "Docker ist nicht installiert!"
exit 1
fi
if ! command -v docker-compose &> /dev/null; then
log_error "Docker Compose ist nicht installiert!"
exit 1
fi
# Zertifikate kopieren
log_info "Kopiere TLS-Zertifikate..."
mkdir -p certs
cp "$PROJECT_ROOT/frontend/certs/frontend.crt" certs/
cp "$PROJECT_ROOT/frontend/certs/frontend.key" certs/
chmod 600 certs/frontend.key
chmod 644 certs/frontend.crt
# Caddyfile Symlink erstellen
log_info "Erstelle Caddyfile Symlink..."
mkdir -p docker/caddy
if [[ ! -L docker/caddy/Caddyfile ]]; then
ln -sf "$PROJECT_ROOT/frontend/docker/caddy/Caddyfile" docker/caddy/Caddyfile
fi
# Docker Images bauen
log_info "Baue Docker Images..."
docker-compose build
# Services starten
log_info "Starte Frontend Services..."
docker-compose up -d
log_success "Frontend Installation abgeschlossen!"
log_info "Frontend verfügbar unter: https://m040tbaraspi001.de040.corpintra.net"
}
health_check_backend() {
log_info "=== Backend Health Check ==="
local max_attempts=30
local attempt=1
while [[ $attempt -le $max_attempts ]]; do
log_info "Versuche Backend-Verbindung (Versuch $attempt/$max_attempts)..."
if curl -k -s --max-time 5 https://raspberrypi/api/test > /dev/null 2>&1; then
log_success "Backend ist erreichbar!"
return 0
fi
sleep 2
((attempt++))
done
log_error "Backend Health Check fehlgeschlagen!"
return 1
}
health_check_frontend() {
log_info "=== Frontend Health Check ==="
local max_attempts=30
local attempt=1
while [[ $attempt -le $max_attempts ]]; do
log_info "Versuche Frontend-Verbindung (Versuch $attempt/$max_attempts)..."
if curl -k -s --max-time 5 https://m040tbaraspi001.de040.corpintra.net/ > /dev/null 2>&1; then
log_success "Frontend ist erreichbar!"
return 0
fi
sleep 2
((attempt++))
done
log_error "Frontend Health Check fehlgeschlagen!"
return 1
}
show_usage() {
echo "Usage: $0 [backend|frontend]"
echo ""
echo "Optionen:"
echo " backend - Installiert das Backend (Python/Flask)"
echo " frontend - Installiert das Frontend (Docker/Next.js)"
echo ""
echo "Beispiele:"
echo " $0 backend # Backend installieren"
echo " $0 frontend # Frontend installieren"
}
# Main
main() {
log_info "MYP Reservation Platform - Installer v3.2"
log_info "Projektpfad: $PROJECT_ROOT"
check_root
check_dependencies
case "${1:-}" in
"backend")
install_backend
health_check_backend
;;
"frontend")
install_frontend
health_check_frontend
;;
*)
show_usage
exit 1
;;
esac
log_success "Installation erfolgreich abgeschlossen!"
}
# Skript ausführen
main "$@"

6
package-lock.json generated
View File

@ -1,6 +0,0 @@
{
"name": "Projektarbeit-MYP",
"lockfileVersion": 3,
"requires": true,
"packages": {}
}

43
scripts/generate_certs.sh Executable file
View File

@ -0,0 +1,43 @@
#!/bin/bash
# Script to generate self-signed TLS certificates for MYP project
# RSA-2048 / SHA-256 certificates with complete DN information
set -e
echo "=== MYP TLS Certificate Generator ==="
# Create directories if they don't exist
mkdir -p backend/app/certs
mkdir -p frontend/certs
# Backend Certificate (raspberrypi)
echo "Generating Backend Certificate..."
openssl req -x509 -newkey rsa:2048 -keyout backend/app/certs/backend.key -out backend/app/certs/backend.crt -days 365 -nodes -sha256 \
-subj "/C=DE/ST=Hamburg/L=Hamburg/O=MYP Reservation Platform/OU=Backend Services/CN=raspberrypi" \
-addext "subjectAltName=DNS:raspberrypi,DNS:localhost,IP:192.168.0.105,IP:127.0.0.1"
# Set appropriate permissions
chmod 600 backend/app/certs/backend.key
chmod 644 backend/app/certs/backend.crt
# Frontend Certificate (m040tbaraspi001)
echo "Generating Frontend Certificate..."
openssl req -x509 -newkey rsa:2048 -keyout frontend/certs/frontend.key -out frontend/certs/frontend.crt -days 365 -nodes -sha256 \
-subj "/C=DE/ST=Hamburg/L=Hamburg/O=MYP Reservation Platform/OU=Frontend Services/CN=m040tbaraspi001" \
-addext "subjectAltName=DNS:m040tbaraspi001,DNS:m040tbaraspi001.de040.corpintra.net,DNS:localhost,IP:192.168.0.109,IP:127.0.0.1"
# Set appropriate permissions
chmod 600 frontend/certs/frontend.key
chmod 644 frontend/certs/frontend.crt
echo "=== Certificate Generation Complete ==="
echo "Backend certificates: backend/app/certs/"
echo "Frontend certificates: frontend/certs/"
echo ""
echo "Certificate information:"
echo "- Type: RSA-2048"
echo "- Hash: SHA-256"
echo "- Validity: 365 days"
echo "- Backend CN: raspberrypi"
echo "- Frontend CN: m040tbaraspi001"