final-cleanup: Produktionsfertige Konfiguration - Alle Ports auf 443 vereinheitlicht, TLS-Zertifikate vorgeneriert, Zentraler Installer erstellt
This commit is contained in:
parent
7aa70cf976
commit
f719f74195
379
COMMON_ERRORS.md
379
COMMON_ERRORS.md
@ -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
259
README.md
@ -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
|
169
ROADMAP.md
169
ROADMAP.md
@ -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
|
@ -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
|
||||
|
@ -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
|
@ -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`.
|
@ -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;
|
||||
}
|
||||
|
@ -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
30
backend/myp.service
Normal 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
|
@ -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:
|
@ -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
191
docs/README.md
Normal 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.
|
||||
|
@ -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)
|
||||
```
|
||||
|
@ -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);
|
||||
});
|
@ -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());
|
||||
|
@ -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:
|
@ -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,49 +8,25 @@ 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
|
||||
@ -58,102 +34,38 @@ services:
|
||||
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
|
||||
caddy_config:
|
||||
driver: local
|
||||
|
||||
frontend_cache:
|
||||
driver: local
|
||||
|
||||
frontend_redis_data:
|
||||
driver: local
|
||||
|
||||
frontend_cdn_cache:
|
||||
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"
|
@ -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:
|
@ -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:
|
||||
|
||||
networks:
|
||||
myp-network:
|
||||
driver: bridge
|
@ -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
|
||||
}
|
||||
# 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
|
||||
|
||||
# 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
|
||||
}
|
||||
|
||||
# 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}
|
||||
@ -80,84 +40,26 @@ m040tbaraspi001.de040.corpintra.net {
|
||||
}
|
||||
}
|
||||
|
||||
# Alle anderen Anfragen zum Frontend weiterleiten
|
||||
handle {
|
||||
reverse_proxy frontend:80 {
|
||||
header_up Host {upstream_hostport}
|
||||
# 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}
|
||||
}
|
||||
|
||||
# Logging
|
||||
log {
|
||||
output file /var/log/caddy/access.log
|
||||
format json
|
||||
}
|
||||
|
||||
# OAuth Callbacks
|
||||
@oauth path /auth/login/callback*
|
||||
handle @oauth {
|
||||
header Cache-Control "no-cache"
|
||||
reverse_proxy frontend:80
|
||||
# Enable compression
|
||||
encode gzip
|
||||
}
|
||||
|
||||
# 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"
|
||||
}
|
||||
}
|
||||
|
||||
# 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
|
||||
}
|
@ -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
@ -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 {
|
||||
|
@ -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();
|
||||
|
@ -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
218
install.sh
Executable 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
6
package-lock.json
generated
@ -1,6 +0,0 @@
|
||||
{
|
||||
"name": "Projektarbeit-MYP",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {}
|
||||
}
|
43
scripts/generate_certs.sh
Executable file
43
scripts/generate_certs.sh
Executable 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"
|
Loading…
x
Reference in New Issue
Block a user