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() {
|
detectApiBaseUrl() {
|
||||||
// Versuche verschiedene Ports zu erkennen
|
|
||||||
const currentHost = window.location.hostname;
|
const currentHost = window.location.hostname;
|
||||||
const currentPort = window.location.port;
|
|
||||||
const currentProtocol = window.location.protocol;
|
const currentProtocol = window.location.protocol;
|
||||||
|
const currentPort = window.location.port;
|
||||||
|
|
||||||
console.log('🔍 Aktuelle URL-Informationen:', {
|
console.log('🔍 Live Dashboard API URL Detection:', { currentHost, currentProtocol, currentPort });
|
||||||
host: currentHost,
|
|
||||||
port: currentPort,
|
|
||||||
protocol: currentProtocol,
|
|
||||||
fullUrl: window.location.href
|
|
||||||
});
|
|
||||||
|
|
||||||
// Wenn wir bereits auf dem richtigen Port sind, verwende relative URLs
|
// Wenn wir bereits auf dem richtigen Port sind, verwende relative URLs
|
||||||
if (currentPort === '5000' || !currentPort) {
|
if (currentPort === '443' || !currentPort) {
|
||||||
console.log('✅ Verwende relative URLs (gleicher Port oder Standard)');
|
console.log('✅ Verwende relative URLs (HTTPS Port 443)');
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wenn wir auf 8443 sind, versuche 5000 (häufiger Fall)
|
// Für alle anderen Fälle, verwende HTTPS auf Port 443
|
||||||
if (currentPort === '8443') {
|
const fallbackUrl = `https://${currentHost}`;
|
||||||
const fallbackUrl = `http://${currentHost}:5000`;
|
console.log('🔄 Fallback zu HTTPS:443:', fallbackUrl);
|
||||||
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);
|
|
||||||
|
|
||||||
return fallbackUrl;
|
return fallbackUrl;
|
||||||
}
|
}
|
||||||
|
@ -12,34 +12,20 @@ let csrfToken;
|
|||||||
// Dynamische API-Base-URL-Erkennung
|
// Dynamische API-Base-URL-Erkennung
|
||||||
function detectApiBaseUrl() {
|
function detectApiBaseUrl() {
|
||||||
const currentHost = window.location.hostname;
|
const currentHost = window.location.hostname;
|
||||||
const currentPort = window.location.port;
|
|
||||||
const currentProtocol = window.location.protocol;
|
const currentProtocol = window.location.protocol;
|
||||||
|
const currentPort = window.location.port;
|
||||||
|
|
||||||
console.log('🔍 Admin API URL-Informationen:', {
|
console.log('🔍 Admin API URL Detection:', { currentHost, currentProtocol, currentPort });
|
||||||
host: currentHost,
|
|
||||||
port: currentPort,
|
|
||||||
protocol: currentProtocol,
|
|
||||||
fullUrl: window.location.href
|
|
||||||
});
|
|
||||||
|
|
||||||
// Wenn wir bereits auf dem richtigen Port sind, verwende relative URLs
|
// Wenn wir bereits auf dem richtigen Port sind, verwende relative URLs
|
||||||
if (currentPort === '5000' || !currentPort) {
|
if (currentPort === '443' || !currentPort) {
|
||||||
console.log('✅ Verwende relative URLs (gleicher Port oder Standard)');
|
console.log('✅ Verwende relative URLs (HTTPS Port 443)');
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wenn wir auf 8443 sind, versuche 5000 (häufiger Fall)
|
// Für alle anderen Fälle, verwende HTTPS auf Port 443
|
||||||
if (currentPort === '8443') {
|
const fallbackUrl = `https://${currentHost}`;
|
||||||
const fallbackUrl = `http://${currentHost}:5000`;
|
console.log('🔄 Admin Fallback zu HTTPS:443:', fallbackUrl);
|
||||||
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);
|
|
||||||
|
|
||||||
return 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
|
// Konfigurationsdatei
|
||||||
const CONFIG_FILE = path.join(__dirname, '../../../.env.local');
|
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
|
// Middleware
|
||||||
app.use(express.json());
|
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
|
# 🎨 MYP Frontend - Produktionsumgebung Konfiguration
|
||||||
# Frontend-Service für die Entwicklung mit Raspberry Pi Backend
|
# Frontend-Service für die Produktion mit Raspberry Pi Backend
|
||||||
|
|
||||||
version: '3.8'
|
version: '3.8'
|
||||||
|
|
||||||
@ -8,49 +8,25 @@ services:
|
|||||||
frontend:
|
frontend:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile.dev
|
dockerfile: Dockerfile
|
||||||
args:
|
container_name: myp-frontend
|
||||||
- BUILDKIT_INLINE_CACHE=1
|
|
||||||
- NODE_ENV=development
|
|
||||||
image: myp/frontend:dev
|
|
||||||
container_name: myp-frontend-dev
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
- NODE_ENV=development
|
- NODE_ENV=production
|
||||||
- NEXT_TELEMETRY_DISABLED=1
|
- NEXT_PUBLIC_API_URL=https://raspberrypi
|
||||||
|
- NEXT_PUBLIC_BACKEND_HOST=raspberrypi
|
||||||
# Backend API Konfiguration (Raspberry Pi)
|
- NEXT_PUBLIC_FRONTEND_URL=https://m040tbaraspi001.de040.corpintra.net
|
||||||
- NEXT_PUBLIC_API_URL=http://192.168.0.105:5000
|
- NEXTAUTH_URL=https://m040tbaraspi001.de040.corpintra.net
|
||||||
- NEXT_PUBLIC_BACKEND_HOST=192.168.0.105:5000
|
- NEXTAUTH_SECRET=${NEXTAUTH_SECRET:-myp-secret-key-2024}
|
||||||
|
- GITHUB_CLIENT_ID=${GITHUB_CLIENT_ID}
|
||||||
# Frontend Server
|
- GITHUB_CLIENT_SECRET=${GITHUB_CLIENT_SECRET}
|
||||||
- PORT=3000
|
- NEXT_PUBLIC_OAUTH_CALLBACK_URL=https://m040tbaraspi001.de040.corpintra.net/auth/login/callback
|
||||||
- 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
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
- .:/app
|
- ./certs:/app/certs
|
||||||
- /app/node_modules
|
|
||||||
- /app/.next
|
|
||||||
- ./public:/app/public:ro
|
|
||||||
|
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000" # Direkter Port-Zugang für Frontend-Server
|
- "3000:3000" # Direkter Port-Zugang für Frontend-Server
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
- frontend-network
|
- myp-network
|
||||||
|
|
||||||
extra_hosts:
|
|
||||||
- "raspberrypi:192.168.0.105"
|
|
||||||
|
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
|
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
@ -58,102 +34,38 @@ services:
|
|||||||
retries: 3
|
retries: 3
|
||||||
start_period: 40s
|
start_period: 40s
|
||||||
|
|
||||||
labels:
|
# === CADDY PROXY ===
|
||||||
- "service.type=frontend"
|
caddy:
|
||||||
- "service.name=myp-frontend-dev"
|
image: caddy:2-alpine
|
||||||
- "service.environment=development"
|
container_name: myp-caddy
|
||||||
|
|
||||||
# === FRONTEND CACHE (Optional: Redis für Session Management) ===
|
|
||||||
frontend-cache:
|
|
||||||
image: redis:7.2-alpine
|
|
||||||
container_name: myp-frontend-cache
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
command: redis-server --appendonly yes --requirepass ${FRONTEND_REDIS_PASSWORD:-frontend_cache_password}
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
- frontend_redis_data:/data
|
|
||||||
|
|
||||||
ports:
|
ports:
|
||||||
- "6380:6379" # Separater Port vom Backend-Cache
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
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
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
- ./public:/usr/share/nginx/html/static:ro
|
- ./docker/caddy/Caddyfile:/etc/caddy/Caddyfile
|
||||||
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
- ./certs:/etc/ssl/certs/myp
|
||||||
- frontend_cdn_cache:/var/cache/nginx
|
- caddy_data:/data
|
||||||
|
- caddy_config:/config
|
||||||
ports:
|
|
||||||
- "8080:80" # Separater Port für statische Assets
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
- frontend-network
|
- myp-network
|
||||||
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- frontend
|
- frontend
|
||||||
|
environment:
|
||||||
healthcheck:
|
- CADDY_INGRESS_NETWORKS=myp-network
|
||||||
test: ["CMD", "curl", "-f", "http://localhost/health"]
|
|
||||||
interval: 30s
|
|
||||||
timeout: 10s
|
|
||||||
retries: 3
|
|
||||||
|
|
||||||
labels:
|
|
||||||
- "service.type=cdn"
|
|
||||||
- "service.name=myp-frontend-cdn"
|
|
||||||
|
|
||||||
# === PERSISTENTE VOLUMES ===
|
# === PERSISTENTE VOLUMES ===
|
||||||
volumes:
|
volumes:
|
||||||
frontend_data:
|
caddy_data:
|
||||||
|
driver: local
|
||||||
|
caddy_config:
|
||||||
driver: local
|
driver: local
|
||||||
|
|
||||||
frontend_cache:
|
# === NETZWERK ===
|
||||||
driver: local
|
|
||||||
|
|
||||||
frontend_redis_data:
|
|
||||||
driver: local
|
|
||||||
|
|
||||||
frontend_cdn_cache:
|
|
||||||
driver: local
|
|
||||||
|
|
||||||
# === FRONTEND-NETZWERK ===
|
|
||||||
networks:
|
networks:
|
||||||
frontend-network:
|
myp-network:
|
||||||
driver: bridge
|
driver: bridge
|
||||||
driver_opts:
|
|
||||||
com.docker.network.enable_ipv6: "false"
|
|
||||||
com.docker.network.bridge.enable_ip_masquerade: "true"
|
|
||||||
labels:
|
labels:
|
||||||
- "description=MYP Frontend Server Netzwerk"
|
- "description=MYP Production Network"
|
||||||
- "project=myp-frontend"
|
- "project=myp-frontend"
|
||||||
- "tier=frontend"
|
- "tier=production"
|
||||||
|
|
||||||
# === 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
|
|
@ -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:
|
services:
|
||||||
# Next.js Frontend
|
# Next.js Frontend
|
||||||
frontend:
|
frontend-app:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
container_name: myp-frontend
|
container_name: myp-frontend-app
|
||||||
restart: unless-stopped
|
|
||||||
environment:
|
environment:
|
||||||
- NODE_ENV=production
|
- NODE_ENV=production
|
||||||
- NEXT_PUBLIC_API_URL=https://raspberrypi:443
|
- NEXT_PUBLIC_API_URL=https://raspberrypi
|
||||||
- NEXT_PUBLIC_BACKEND_HOST=raspberrypi:443
|
- HOSTNAME=m040tbaraspi001.de040.corpintra.net
|
||||||
- PORT=80
|
|
||||||
volumes:
|
|
||||||
- ./certs:/app/certs
|
|
||||||
ports:
|
|
||||||
- "80"
|
|
||||||
networks:
|
networks:
|
||||||
- myp-network
|
- myp-network
|
||||||
|
restart: unless-stopped
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "wget", "--spider", "http://localhost:80/health"]
|
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
start_period: 40s
|
|
||||||
|
|
||||||
# Caddy Proxy für SSL-Terminierung
|
# Caddy Proxy für SSL-Terminierung
|
||||||
caddy:
|
caddy:
|
||||||
image: caddy:2.7-alpine
|
image: caddy:2-alpine
|
||||||
container_name: myp-caddy
|
container_name: myp-caddy
|
||||||
restart: unless-stopped
|
|
||||||
ports:
|
ports:
|
||||||
- "80:80"
|
- "80:80"
|
||||||
- "443:443"
|
- "443:443"
|
||||||
volumes:
|
volumes:
|
||||||
- ./docker/caddy/Caddyfile:/etc/caddy/Caddyfile
|
- ./docker/caddy/Caddyfile:/etc/caddy/Caddyfile
|
||||||
- ./certs:/etc/caddy/certs
|
- ./certs:/etc/ssl/certs/myp
|
||||||
- caddy_data:/data
|
- caddy_data:/data
|
||||||
- caddy_config:/config
|
- caddy_config:/config
|
||||||
networks:
|
networks:
|
||||||
- myp-network
|
- myp-network
|
||||||
depends_on:
|
depends_on:
|
||||||
- frontend
|
- frontend-app
|
||||||
extra_hosts:
|
restart: unless-stopped
|
||||||
- "host.docker.internal:host-gateway"
|
|
||||||
- "raspberrypi:192.168.0.105"
|
|
||||||
- "m040tbaraspi001.de040.corpintra.net:127.0.0.1"
|
|
||||||
environment:
|
environment:
|
||||||
- CADDY_HOST=m040tbaraspi001.de040.corpintra.net
|
- CADDY_INGRESS_NETWORKS=myp-network
|
||||||
- CADDY_DOMAIN=m040tbaraspi001.de040.corpintra.net
|
|
||||||
cap_add:
|
|
||||||
- NET_ADMIN
|
|
||||||
|
|
||||||
networks:
|
|
||||||
myp-network:
|
|
||||||
driver: bridge
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
caddy_data:
|
caddy_data:
|
||||||
caddy_config:
|
caddy_config:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
myp-network:
|
||||||
|
driver: bridge
|
@ -1,76 +1,36 @@
|
|||||||
{
|
# HTTP to HTTPS redirect
|
||||||
debug
|
:80 {
|
||||||
auto_https off
|
redir https://{host}{uri} permanent
|
||||||
local_certs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Produktionsumgebung - Frontend auf Port 80/443 mit selbstsigniertem Zertifikat
|
# HTTPS Frontend
|
||||||
:80, :443 {
|
m040tbaraspi001.de040.corpintra.net:443 {
|
||||||
# TLS mit automatisch generierten selbstsignierten Zertifikaten
|
# TLS configuration with custom certificates
|
||||||
tls internal {
|
tls /etc/ssl/certs/myp/frontend.crt /etc/ssl/certs/myp/frontend.key
|
||||||
on_demand
|
|
||||||
}
|
|
||||||
|
|
||||||
# API Anfragen zum Backend (Raspberry Pi) weiterleiten
|
# Security headers
|
||||||
@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
|
|
||||||
header {
|
header {
|
||||||
|
# Enable HSTS
|
||||||
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
||||||
|
# XSS Protection
|
||||||
X-Content-Type-Options "nosniff"
|
X-Content-Type-Options "nosniff"
|
||||||
X-Frame-Options "SAMEORIGIN"
|
X-Frame-Options "DENY"
|
||||||
Referrer-Policy "strict-origin-when-cross-origin"
|
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
|
||||||
# Spezifische Hostname-Konfiguration für Mercedes-Benz Werk 040 Berlin (falls benötigt)
|
-Server
|
||||||
m040tbaraspi001.de040.corpintra.net {
|
|
||||||
# TLS mit automatisch generierten selbstsignierten Zertifikaten
|
|
||||||
tls internal {
|
|
||||||
on_demand
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# API Anfragen zum Backend (Raspberry Pi) weiterleiten
|
# Health check endpoint
|
||||||
@api {
|
handle /health {
|
||||||
path /api/* /health
|
respond "OK" 200
|
||||||
}
|
}
|
||||||
handle @api {
|
|
||||||
uri strip_prefix /api
|
# API proxy to backend
|
||||||
reverse_proxy raspberrypi:443 {
|
handle /api/* {
|
||||||
|
reverse_proxy https://raspberrypi {
|
||||||
transport http {
|
transport http {
|
||||||
tls
|
|
||||||
tls_insecure_skip_verify
|
tls_insecure_skip_verify
|
||||||
}
|
}
|
||||||
header_up Host {upstream_hostport}
|
header_up Host {upstream_hostport}
|
||||||
@ -80,84 +40,26 @@ m040tbaraspi001.de040.corpintra.net {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Alle anderen Anfragen zum Frontend weiterleiten
|
# Frontend application
|
||||||
handle {
|
reverse_proxy frontend-app:3000 {
|
||||||
reverse_proxy frontend:80 {
|
header_up Host {host}
|
||||||
header_up Host {upstream_hostport}
|
|
||||||
header_up X-Real-IP {remote_host}
|
header_up X-Real-IP {remote_host}
|
||||||
header_up X-Forwarded-For {remote_host}
|
header_up X-Forwarded-For {remote_host}
|
||||||
header_up X-Forwarded-Proto {scheme}
|
header_up X-Forwarded-Proto {scheme}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
log {
|
||||||
|
output file /var/log/caddy/access.log
|
||||||
|
format json
|
||||||
}
|
}
|
||||||
|
|
||||||
# OAuth Callbacks
|
# Enable compression
|
||||||
@oauth path /auth/login/callback*
|
encode gzip
|
||||||
handle @oauth {
|
|
||||||
header Cache-Control "no-cache"
|
|
||||||
reverse_proxy frontend:80
|
|
||||||
}
|
|
||||||
|
|
||||||
# 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)
|
# Fallback for direct IP access
|
||||||
localhost, 127.0.0.1 {
|
192.168.0.109:443 {
|
||||||
# API Anfragen zum Raspberry Pi Backend weiterleiten
|
tls /etc/ssl/certs/myp/frontend.crt /etc/ssl/certs/myp/frontend.key
|
||||||
@api {
|
redir https://m040tbaraspi001.de040.corpintra.net{uri} permanent
|
||||||
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"
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -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) {
|
export async function GET(request: NextRequest) {
|
||||||
try {
|
try {
|
||||||
// Prüfe Backend-Verbindung
|
// 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';
|
let backendStatus = 'unknown';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -16,31 +16,16 @@ const getApiBaseUrl = () => {
|
|||||||
|
|
||||||
// Verbindungsoptionen in Prioritätsreihenfolge
|
// Verbindungsoptionen in Prioritätsreihenfolge
|
||||||
return {
|
return {
|
||||||
primary: `https://${hostname}:443`,
|
primary: `https://${hostname}`,
|
||||||
fallbacks: [
|
fallbacks: [
|
||||||
`http://${hostname}:443`,
|
`https://raspberrypi`,
|
||||||
`https://${hostname}:80`,
|
`https://192.168.0.105`,
|
||||||
`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`,
|
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Standardwert für serverseitiges Rendering
|
// Standardwert für serverseitiges Rendering
|
||||||
return `https://raspberrypi:443`;
|
return `https://raspberrypi`;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const API_BASE_URL = getApiBaseUrl();
|
export const API_BASE_URL = getApiBaseUrl();
|
||||||
@ -63,8 +48,8 @@ const getFrontendUrl = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Priorität 3: Default für Localhost
|
// Priorität 3: Default für Localhost (development)
|
||||||
return "https://localhost:3000";
|
return "https://m040tbaraspi001.de040.corpintra.net";
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FRONTEND_URL = getFrontendUrl();
|
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