"Add test script and guide for separate servers setup (feat)"
This commit is contained in:
parent
03ff4260e2
commit
c1e8ee01c5
@ -10,7 +10,7 @@ PYTHONUNBUFFERED=1
|
||||
# SQLite (Default)
|
||||
DATABASE_PATH=instance/myp.db
|
||||
|
||||
# PostgreSQL (Optional)
|
||||
# PostgreSQL (Optional - für Produktionsumgebung empfohlen)
|
||||
DB_NAME=myp_backend
|
||||
DB_USER=myp_user
|
||||
DB_PASSWORD=secure_backend_password
|
||||
@ -48,18 +48,38 @@ REDIS_DB=0
|
||||
# === LOGGING ===
|
||||
LOG_LEVEL=INFO
|
||||
LOG_FILE=logs/backend.log
|
||||
LOG_MAX_SIZE=10485760
|
||||
LOG_MAX_BYTES=10485760
|
||||
LOG_BACKUP_COUNT=5
|
||||
|
||||
# === DATEISYSTEM ===
|
||||
UPLOAD_FOLDER=uploads
|
||||
MAX_CONTENT_LENGTH=16777216
|
||||
# === PRODUKTIONS-KONFIGURATION ===
|
||||
# Gunicorn-Einstellungen
|
||||
WORKERS=4
|
||||
BIND_ADDRESS=0.0.0.0:5000
|
||||
TIMEOUT=30
|
||||
KEEP_ALIVE=5
|
||||
MAX_REQUESTS=1000
|
||||
MAX_REQUESTS_JITTER=100
|
||||
|
||||
# === SICHERHEITS-EINSTELLUNGEN ===
|
||||
WTF_CSRF_ENABLED=true
|
||||
FORCE_HTTPS=false
|
||||
RATE_LIMIT_ENABLED=true
|
||||
MAX_REQUESTS_PER_MINUTE=60
|
||||
RATE_LIMIT_WINDOW_MINUTES=15
|
||||
|
||||
# === MONITORING ===
|
||||
HEALTH_CHECK_INTERVAL=30
|
||||
METRICS_ENABLED=true
|
||||
METRICS_PORT=9090
|
||||
|
||||
# === JOB-KONFIGURATION ===
|
||||
JOB_CHECK_INTERVAL=60
|
||||
SOCKET_CHECK_INTERVAL=120
|
||||
|
||||
# === DATEISYSTEM ===
|
||||
UPLOAD_FOLDER=uploads
|
||||
MAX_CONTENT_LENGTH=16777216
|
||||
|
||||
# === ENTWICKLUNG ===
|
||||
DEBUG=false
|
||||
TESTING=false
|
||||
|
@ -1,7 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
# MYP Backend Installations-Skript
|
||||
# Dieses Skript installiert das Backend mit Docker und Host-Netzwerkanbindung
|
||||
# 🏭 MYP Backend - Installations-Skript
|
||||
# Installiert das Backend für Produktionsbetrieb oder Entwicklung
|
||||
|
||||
set -e
|
||||
|
||||
# Farbcodes für Ausgabe
|
||||
RED='\033[0;31m'
|
||||
@ -15,496 +17,335 @@ log() {
|
||||
echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
|
||||
}
|
||||
|
||||
success_log() {
|
||||
echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] SUCCESS:${NC} $1"
|
||||
}
|
||||
|
||||
warning_log() {
|
||||
echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARNING:${NC} $1"
|
||||
}
|
||||
|
||||
error_log() {
|
||||
echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] FEHLER:${NC} $1" >&2
|
||||
}
|
||||
|
||||
# Funktion zum Bereinigen vorhandener Installationen
|
||||
cleanup_existing_installation() {
|
||||
log "${YELLOW}Bereinige vorhandene Installation...${NC}"
|
||||
# Banner
|
||||
echo "========================================"
|
||||
echo "🏭 MYP Backend - Installation"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
|
||||
# Stoppe und entferne existierende Container
|
||||
if docker ps -a | grep -q "myp-backend"; then
|
||||
log "Stoppe und entferne existierenden Backend-Container..."
|
||||
docker stop myp-backend &>/dev/null || true
|
||||
docker rm myp-backend &>/dev/null || true
|
||||
fi
|
||||
|
||||
# Entferne Docker Images
|
||||
if docker images | grep -q "myp-backend"; then
|
||||
log "Entferne existierendes Backend-Image..."
|
||||
docker rmi myp-backend &>/dev/null || true
|
||||
fi
|
||||
|
||||
log "${GREEN}Bereinigung abgeschlossen.${NC}"
|
||||
}
|
||||
|
||||
# Pfade definieren
|
||||
# Arbeitsverzeichnis
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
BACKEND_DIR="$SCRIPT_DIR"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
# Bereinige existierende Installation
|
||||
cleanup_existing_installation
|
||||
log "Arbeitsverzeichnis: $SCRIPT_DIR"
|
||||
|
||||
# Funktion zur Installation von Docker und Docker Compose für Raspberry Pi
|
||||
install_docker() {
|
||||
log "${YELLOW}Docker ist nicht installiert. Installation wird gestartet...${NC}"
|
||||
|
||||
# Erkenne Raspberry Pi
|
||||
if [ -f /proc/device-tree/model ] && grep -q "Raspberry Pi" /proc/device-tree/model; then
|
||||
log "${GREEN}Raspberry Pi erkannt. Installiere Docker für ARM-Architektur...${NC}"
|
||||
IS_RASPBERRY_PI=true
|
||||
else
|
||||
IS_RASPBERRY_PI=false
|
||||
fi
|
||||
|
||||
# Aktualisiere Paketindex
|
||||
if ! sudo apt-get update; then
|
||||
error_log "Konnte Paketindex nicht aktualisieren. Bitte manuell installieren."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Installiere erforderliche Pakete
|
||||
if ! sudo apt-get install -y apt-transport-https ca-certificates curl gnupg software-properties-common; then
|
||||
error_log "Konnte erforderliche Pakete nicht installieren. Bitte manuell installieren."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Raspberry Pi-spezifische Installation
|
||||
if [ "$IS_RASPBERRY_PI" = true ]; then
|
||||
# Setze Systemarchitektur für Raspberry Pi (armhf oder arm64)
|
||||
ARCH=$(dpkg --print-architecture)
|
||||
log "Erkannte Systemarchitektur: ${ARCH}"
|
||||
|
||||
# Installiere Docker mit convenience script (für Raspberry Pi empfohlen)
|
||||
log "${YELLOW}Installiere Docker mit dem convenience script...${NC}"
|
||||
curl -fsSL https://get.docker.com -o get-docker.sh
|
||||
sudo sh get-docker.sh
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
error_log "Docker-Installation fehlgeschlagen. Bitte manuell installieren."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# Standard-Installation für andere Systeme
|
||||
# Füge Docker's offiziellen GPG-Schlüssel hinzu
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
|
||||
|
||||
# Füge Docker-Repository hinzu
|
||||
if ! sudo add-apt-repository "deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"; then
|
||||
error_log "Konnte Docker-Repository nicht hinzufügen. Prüfen Sie, ob Ihr System unterstützt wird."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Aktualisiere Paketindex erneut
|
||||
sudo apt-get update
|
||||
|
||||
# Installiere Docker
|
||||
if ! sudo apt-get install -y docker-ce docker-ce-cli containerd.io; then
|
||||
error_log "Konnte Docker nicht installieren. Bitte manuell installieren."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Füge aktuellen Benutzer zur Docker-Gruppe hinzu
|
||||
sudo usermod -aG docker "$USER"
|
||||
|
||||
log "${GREEN}Docker wurde installiert.${NC}"
|
||||
log "${YELLOW}WICHTIG: Möglicherweise müssen Sie sich neu anmelden, damit die Gruppenänderung wirksam wird.${NC}"
|
||||
|
||||
# Prüfen, ob Docker Compose v2 Plugin verfügbar ist (bevorzugt, da moderner)
|
||||
log "${YELLOW}Prüfe Docker Compose Version...${NC}"
|
||||
|
||||
if docker compose version &> /dev/null; then
|
||||
log "${GREEN}Docker Compose v2 Plugin ist bereits installiert.${NC}"
|
||||
DOCKER_COMPOSE_V2=true
|
||||
else
|
||||
log "${YELLOW}Docker Compose v2 Plugin nicht gefunden. Versuche Docker Compose v1 zu installieren...${NC}"
|
||||
DOCKER_COMPOSE_V2=false
|
||||
|
||||
if [ "$IS_RASPBERRY_PI" = true ]; then
|
||||
# Für Raspberry Pi ist es besser, die richtige Architektur zu verwenden
|
||||
if [ "$ARCH" = "armhf" ]; then
|
||||
log "Installiere Docker Compose für armhf (32-bit)..."
|
||||
sudo curl -L "https://github.com/docker/compose/releases/download/v2.6.1/docker-compose-linux-armv7" -o /usr/local/bin/docker-compose
|
||||
elif [ "$ARCH" = "arm64" ]; then
|
||||
log "Installiere Docker Compose für arm64 (64-bit)..."
|
||||
sudo curl -L "https://github.com/docker/compose/releases/download/v2.6.1/docker-compose-linux-aarch64" -o /usr/local/bin/docker-compose
|
||||
else
|
||||
# Fallback auf v1.29.2 für unbekannte ARM-Architekturen
|
||||
log "Verwende automatische Architekturerkennung für Docker Compose v1.29.2..."
|
||||
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||
fi
|
||||
else
|
||||
# Für andere Systeme versuche zuerst v2, dann v1.29.2 als Fallback
|
||||
log "Installiere Docker Compose v2 für $(uname -s)/$(uname -m)..."
|
||||
if ! sudo curl -L "https://github.com/docker/compose/releases/download/v2.6.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose; then
|
||||
log "${YELLOW}Konnte Docker Compose v2 nicht herunterladen. Versuche v1.29.2...${NC}"
|
||||
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
error_log "Konnte Docker Compose nicht herunterladen. Bitte manuell installieren."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sudo chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
log "${GREEN}Docker Compose wurde installiert.${NC}"
|
||||
fi
|
||||
|
||||
# Starte Docker-Dienst
|
||||
if command -v systemctl &> /dev/null; then
|
||||
sudo systemctl enable docker
|
||||
sudo systemctl start docker
|
||||
elif command -v service &> /dev/null; then
|
||||
sudo service docker enable
|
||||
sudo service docker start
|
||||
fi
|
||||
}
|
||||
|
||||
# Prüfen ob Docker installiert ist
|
||||
if ! command -v docker &> /dev/null; then
|
||||
log "${YELLOW}Docker ist nicht installiert.${NC}"
|
||||
read -p "Möchten Sie Docker installieren? (j/n): " install_docker_choice
|
||||
if [[ "$install_docker_choice" == "j" ]]; then
|
||||
install_docker
|
||||
else
|
||||
error_log "Docker wird für die Installation benötigt. Bitte installieren Sie Docker manuell."
|
||||
log "Siehe: https://docs.docker.com/get-docker/"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Prüfen ob Docker Daemon läuft
|
||||
if ! docker info &> /dev/null; then
|
||||
log "${YELLOW}Docker-Daemon läuft nicht. Versuche, den Dienst zu starten...${NC}"
|
||||
|
||||
# Versuche, Docker zu starten
|
||||
if command -v systemctl &> /dev/null; then
|
||||
sudo systemctl start docker
|
||||
elif command -v service &> /dev/null; then
|
||||
sudo service docker start
|
||||
else
|
||||
error_log "Konnte Docker-Daemon nicht starten. Bitte starten Sie den Docker-Dienst manuell."
|
||||
log "Starten mit: sudo systemctl start docker oder sudo service docker start"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Prüfe erneut, ob Docker läuft
|
||||
if ! docker info &> /dev/null; then
|
||||
error_log "Docker-Daemon konnte nicht gestartet werden. Bitte starten Sie den Docker-Dienst manuell."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "${GREEN}Docker-Daemon wurde erfolgreich gestartet.${NC}"
|
||||
fi
|
||||
|
||||
# Prüfen ob Docker Compose installiert ist
|
||||
if docker compose version &> /dev/null; then
|
||||
log "${GREEN}Docker Compose v2 Plugin ist bereits installiert.${NC}"
|
||||
DOCKER_COMPOSE_V2=true
|
||||
elif command -v docker-compose &> /dev/null; then
|
||||
log "${GREEN}Docker Compose v1 ist bereits installiert.${NC}"
|
||||
DOCKER_COMPOSE_V2=false
|
||||
# Installation-Modus bestimmen
|
||||
INSTALL_MODE="development"
|
||||
if [ "$1" = "--production" ]; then
|
||||
INSTALL_MODE="production"
|
||||
log "🚀 Produktions-Installation gewählt"
|
||||
elif [ "$1" = "--development" ]; then
|
||||
INSTALL_MODE="development"
|
||||
log "🔧 Entwicklungs-Installation gewählt"
|
||||
else
|
||||
log "${YELLOW}Docker Compose ist nicht installiert.${NC}"
|
||||
DOCKER_COMPOSE_V2=false
|
||||
read -p "Möchten Sie Docker Compose installieren? (j/n): " install_compose_choice
|
||||
if [[ "$install_compose_choice" == "j" ]]; then
|
||||
log "${YELLOW}Installiere Docker Compose...${NC}"
|
||||
echo "Wählen Sie den Installationsmodus:"
|
||||
echo "1) Entwicklung (empfohlen für lokale Tests)"
|
||||
echo "2) Produktion (für Server-Deployment)"
|
||||
read -p "Ihre Wahl (1/2): " choice
|
||||
|
||||
# Prüfe ob das Betriebssystem ARM-basiert ist (z.B. Raspberry Pi)
|
||||
if grep -q "arm" /proc/cpuinfo 2> /dev/null; then
|
||||
ARCH=$(dpkg --print-architecture 2> /dev/null || echo "unknown")
|
||||
IS_RASPBERRY_PI=true
|
||||
else
|
||||
IS_RASPBERRY_PI=false
|
||||
fi
|
||||
|
||||
# Versuche zuerst Docker Compose v2 zu installieren
|
||||
if [ "$IS_RASPBERRY_PI" = true ]; then
|
||||
if [ "$ARCH" = "armhf" ]; then
|
||||
log "Installiere Docker Compose für armhf (32-bit)..."
|
||||
sudo curl -L "https://github.com/docker/compose/releases/download/v2.6.1/docker-compose-linux-armv7" -o /usr/local/bin/docker-compose
|
||||
elif [ "$ARCH" = "arm64" ]; then
|
||||
log "Installiere Docker Compose für arm64 (64-bit)..."
|
||||
sudo curl -L "https://github.com/docker/compose/releases/download/v2.6.1/docker-compose-linux-aarch64" -o /usr/local/bin/docker-compose
|
||||
else
|
||||
log "Verwende automatische Architekturerkennung für Docker Compose v1.29.2..."
|
||||
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||
fi
|
||||
else
|
||||
log "Installiere Docker Compose v2 für $(uname -s)/$(uname -m)..."
|
||||
if ! sudo curl -L "https://github.com/docker/compose/releases/download/v2.6.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose; then
|
||||
log "${YELLOW}Konnte Docker Compose v2 nicht herunterladen. Versuche v1.29.2...${NC}"
|
||||
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
error_log "Konnte Docker Compose nicht herunterladen. Bitte manuell installieren."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sudo chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
log "${GREEN}Docker Compose wurde installiert.${NC}"
|
||||
else
|
||||
error_log "Docker Compose wird für die Installation benötigt. Bitte installieren Sie es manuell."
|
||||
log "Siehe: https://docs.docker.com/compose/install/"
|
||||
exit 1
|
||||
fi
|
||||
case $choice in
|
||||
1) INSTALL_MODE="development" ;;
|
||||
2) INSTALL_MODE="production" ;;
|
||||
*) log "Verwende Standard-Entwicklungsmodus" && INSTALL_MODE="development" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Prüfen ob wget installiert ist (wird für healthcheck verwendet)
|
||||
if ! command -v wget &> /dev/null; then
|
||||
error_log "wget ist nicht installiert, wird aber für den Container-Healthcheck benötigt."
|
||||
log "Installation mit: sudo apt-get install wget"
|
||||
exit 1
|
||||
fi
|
||||
log "Installationsmodus: $INSTALL_MODE"
|
||||
|
||||
# Wechsle ins Backend-Verzeichnis
|
||||
log "Wechsle ins Verzeichnis: $BACKEND_DIR"
|
||||
cd "$BACKEND_DIR" || {
|
||||
error_log "Konnte nicht ins Verzeichnis $BACKEND_DIR wechseln."
|
||||
exit 1
|
||||
# Bereinige vorherige Installation
|
||||
cleanup_existing_installation() {
|
||||
log "🧹 Bereinige vorherige Installation..."
|
||||
|
||||
# Stoppe laufende Prozesse
|
||||
if pgrep -f "flask run" > /dev/null; then
|
||||
log "Stoppe laufende Flask-Prozesse..."
|
||||
pkill -f "flask run" || true
|
||||
fi
|
||||
|
||||
if pgrep -f "gunicorn" > /dev/null; then
|
||||
log "Stoppe laufende Gunicorn-Prozesse..."
|
||||
pkill -f "gunicorn.*wsgi:application" || true
|
||||
fi
|
||||
|
||||
# Entferne alte virtuelle Umgebung
|
||||
if [ -d "venv" ]; then
|
||||
log "Entferne alte virtuelle Umgebung..."
|
||||
rm -rf venv
|
||||
fi
|
||||
|
||||
success_log "Bereinigung abgeschlossen"
|
||||
}
|
||||
|
||||
# Prüfe ob Dockerfile existiert
|
||||
if [ ! -f "Dockerfile" ]; then
|
||||
error_log "Dockerfile nicht gefunden in $BACKEND_DIR."
|
||||
exit 1
|
||||
fi
|
||||
# System-Dependencies prüfen und installieren
|
||||
install_system_dependencies() {
|
||||
log "🔧 Prüfe System-Dependencies..."
|
||||
|
||||
# Prüfe ob docker-compose.yml existiert
|
||||
if [ ! -f "docker-compose.yml" ]; then
|
||||
error_log "docker-compose.yml nicht gefunden in $BACKEND_DIR."
|
||||
exit 1
|
||||
fi
|
||||
# Betriebssystem erkennen
|
||||
if [ -f /etc/os-release ]; then
|
||||
. /etc/os-release
|
||||
OS=$NAME
|
||||
VER=$VERSION_ID
|
||||
elif type lsb_release >/dev/null 2>&1; then
|
||||
OS=$(lsb_release -si)
|
||||
VER=$(lsb_release -sr)
|
||||
else
|
||||
OS=$(uname -s)
|
||||
VER=$(uname -r)
|
||||
fi
|
||||
|
||||
# Erstelle .env-Datei
|
||||
log "${YELLOW}Erstelle .env Datei...${NC}"
|
||||
cat > .env << EOL
|
||||
SECRET_KEY=7445630171969DFAC92C53CEC92E67A9CB2E00B3CB2F
|
||||
log "Erkanntes System: $OS $VER"
|
||||
|
||||
# Python 3 prüfen
|
||||
if ! command -v python3 &> /dev/null; then
|
||||
error_log "Python 3 ist nicht installiert!"
|
||||
log "Installationsanleitung:"
|
||||
if [[ "$OS" == *"Ubuntu"* ]] || [[ "$OS" == *"Debian"* ]]; then
|
||||
log "sudo apt update && sudo apt install python3 python3-pip python3-venv"
|
||||
elif [[ "$OS" == *"CentOS"* ]] || [[ "$OS" == *"Red Hat"* ]]; then
|
||||
log "sudo yum install python3 python3-pip"
|
||||
elif [[ "$OS" == *"Alpine"* ]]; then
|
||||
log "sudo apk add python3 py3-pip"
|
||||
else
|
||||
log "Bitte installieren Sie Python 3 manuell für Ihr System"
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Python-Version prüfen
|
||||
PYTHON_VERSION=$(python3 -c "import sys; print('.'.join(map(str, sys.version_info[:2])))")
|
||||
log "Python-Version: $PYTHON_VERSION"
|
||||
|
||||
if python3 -c "import sys; exit(0 if sys.version_info >= (3, 8) else 1)"; then
|
||||
success_log "Python-Version ist kompatibel (>= 3.8)"
|
||||
else
|
||||
error_log "Python-Version ist zu alt! Benötigt wird mindestens Python 3.8"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# pip prüfen
|
||||
if ! command -v pip3 &> /dev/null; then
|
||||
error_log "pip3 ist nicht installiert!"
|
||||
log "Installiere pip3..."
|
||||
if [[ "$OS" == *"Ubuntu"* ]] || [[ "$OS" == *"Debian"* ]]; then
|
||||
sudo apt install python3-pip
|
||||
else
|
||||
error_log "Bitte installieren Sie pip3 manuell"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Weitere notwendige System-Pakete prüfen
|
||||
if [[ "$OS" == *"Ubuntu"* ]] || [[ "$OS" == *"Debian"* ]]; then
|
||||
log "Prüfe System-Pakete für Ubuntu/Debian..."
|
||||
|
||||
# Prüfe ob build-essential installiert ist (für Compilation von Python-Paketen)
|
||||
if ! dpkg -l | grep -q build-essential; then
|
||||
log "Installiere build-essential..."
|
||||
sudo apt update
|
||||
sudo apt install -y build-essential python3-dev
|
||||
fi
|
||||
|
||||
# Prüfe curl für Health-Checks
|
||||
if ! command -v curl &> /dev/null; then
|
||||
log "Installiere curl..."
|
||||
sudo apt install -y curl
|
||||
fi
|
||||
fi
|
||||
|
||||
success_log "System-Dependencies sind verfügbar"
|
||||
}
|
||||
|
||||
# Python virtuelle Umgebung erstellen
|
||||
create_virtual_environment() {
|
||||
log "🐍 Erstelle Python virtuelle Umgebung..."
|
||||
|
||||
# Erstelle virtuelle Umgebung
|
||||
python3 -m venv venv
|
||||
|
||||
# Aktiviere virtuelle Umgebung
|
||||
source venv/bin/activate
|
||||
|
||||
# Upgrade pip in virtueller Umgebung
|
||||
log "Aktualisiere pip..."
|
||||
pip install --upgrade pip
|
||||
|
||||
success_log "Virtuelle Umgebung erstellt und aktiviert"
|
||||
}
|
||||
|
||||
# Python-Dependencies installieren
|
||||
install_python_dependencies() {
|
||||
log "📦 Installiere Python-Dependencies..."
|
||||
|
||||
# Aktiviere virtuelle Umgebung
|
||||
source venv/bin/activate
|
||||
|
||||
# Installiere Requirements
|
||||
if [ -f "requirements.txt" ]; then
|
||||
log "Installiere aus requirements.txt..."
|
||||
pip install -r requirements.txt
|
||||
else
|
||||
error_log "requirements.txt nicht gefunden!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Produktions-spezifische Dependencies
|
||||
if [ "$INSTALL_MODE" = "production" ]; then
|
||||
log "Installiere Produktions-Dependencies..."
|
||||
pip install gunicorn supervisor
|
||||
fi
|
||||
|
||||
success_log "Python-Dependencies installiert"
|
||||
}
|
||||
|
||||
# Konfiguration vorbereiten
|
||||
prepare_configuration() {
|
||||
log "⚙️ Bereite Konfiguration vor..."
|
||||
|
||||
# Erstelle notwendige Verzeichnisse
|
||||
mkdir -p instance logs migrations/versions
|
||||
|
||||
# Kopiere Beispiel-Umgebungsvariablen falls nicht vorhanden
|
||||
if [ ! -f "env.backend" ]; then
|
||||
if [ -f "env.example" ]; then
|
||||
log "Erstelle env.backend aus Vorlage..."
|
||||
cp env.example env.backend
|
||||
else
|
||||
log "Erstelle Standard env.backend..."
|
||||
cat > env.backend << EOF
|
||||
# MYP Backend Konfiguration
|
||||
FLASK_ENV=$INSTALL_MODE
|
||||
SECRET_KEY=$(python3 -c "import secrets; print(secrets.token_hex(32))")
|
||||
DATABASE_PATH=instance/myp.db
|
||||
TAPO_USERNAME=till.tomczak@mercedes-benz.com
|
||||
TAPO_PASSWORD=744563017196A
|
||||
PRINTERS={"Printer 1": {"ip": "192.168.0.100"}, "Printer 2": {"ip": "192.168.0.101"}, "Printer 3": {"ip": "192.168.0.102"}, "Printer 4": {"ip": "192.168.0.103"}, "Printer 5": {"ip": "192.168.0.104"}, "Printer 6": {"ip": "192.168.0.106"}}
|
||||
EOL
|
||||
|
||||
if [ ! -f ".env" ]; then
|
||||
error_log "Konnte .env-Datei nicht erstellen. Prüfen Sie die Berechtigungen."
|
||||
exit 1
|
||||
fi
|
||||
log "${GREEN}.env Datei erfolgreich erstellt${NC}"
|
||||
|
||||
# Verzeichnisse erstellen
|
||||
log "Erstelle benötigte Verzeichnisse"
|
||||
if ! mkdir -p logs; then
|
||||
error_log "Konnte Verzeichnis 'logs' nicht erstellen. Prüfen Sie die Berechtigungen."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! mkdir -p instance; then
|
||||
error_log "Konnte Verzeichnis 'instance' nicht erstellen. Prüfen Sie die Berechtigungen."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Docker-Image bauen und starten
|
||||
log "${YELLOW}Baue und starte Backend-Container...${NC}"
|
||||
log "${YELLOW}Dies kann auf einem Raspberry Pi einige Minuten dauern - bitte geduldig sein${NC}"
|
||||
|
||||
# Prüfe, ob Docker-Daemon läuft
|
||||
if ! docker info &>/dev/null; then
|
||||
log "${YELLOW}Docker-Daemon scheint nicht zu laufen. Versuche zu starten...${NC}"
|
||||
|
||||
# Versuche Docker zu starten
|
||||
if command -v systemctl &>/dev/null; then
|
||||
sudo systemctl start docker || true
|
||||
sleep 5
|
||||
elif command -v service &>/dev/null; then
|
||||
sudo service docker start || true
|
||||
sleep 5
|
||||
LOG_LEVEL=INFO
|
||||
JOB_CHECK_INTERVAL=60
|
||||
PRINTERS={}
|
||||
TAPO_USERNAME=
|
||||
TAPO_PASSWORD=
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Prüfe erneut, ob Docker jetzt läuft
|
||||
if ! docker info &>/dev/null; then
|
||||
error_log "Docker-Daemon konnte nicht gestartet werden."
|
||||
log "Führen Sie vor der Installation bitte folgende Befehle aus:"
|
||||
log " sudo systemctl start docker"
|
||||
log " sudo systemctl enable docker"
|
||||
log "Starten Sie dann das Installationsskript erneut."
|
||||
exit 1
|
||||
warning_log "env.backend wurde erstellt. Bitte anpassen!"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Docker-Rechte prüfen
|
||||
if ! docker ps &>/dev/null; then
|
||||
error_log "Sie haben keine Berechtigung, Docker ohne sudo zu verwenden."
|
||||
log "Bitte führen Sie folgenden Befehl aus und melden Sie sich danach neu an:"
|
||||
log " sudo usermod -aG docker $USER"
|
||||
exit 1
|
||||
fi
|
||||
success_log "Konfiguration vorbereitet"
|
||||
}
|
||||
|
||||
# Prüfen, ob erforderliche Basis-Images lokal verfügbar sind
|
||||
if ! docker image inspect python:3-slim &>/dev/null; then
|
||||
log "${YELLOW}Prüfe und setze DNS-Server für Docker...${NC}"
|
||||
# Datenbank initialisieren
|
||||
initialize_database() {
|
||||
log "🗄️ Initialisiere Datenbank..."
|
||||
|
||||
# DNS-Einstellungen prüfen und anpassen
|
||||
if [ -f /etc/docker/daemon.json ]; then
|
||||
log "Bestehende Docker-Konfiguration gefunden."
|
||||
# Aktiviere virtuelle Umgebung
|
||||
source venv/bin/activate
|
||||
|
||||
# Lade Umgebungsvariablen
|
||||
if [ -f "env.backend" ]; then
|
||||
export $(cat env.backend | grep -v '^#' | grep -v '^$' | xargs)
|
||||
fi
|
||||
|
||||
# Setze Flask-App
|
||||
export FLASK_APP=app.py
|
||||
export FLASK_ENV=$INSTALL_MODE
|
||||
|
||||
# Initialisiere Datenbank
|
||||
python3 -c "
|
||||
from app import create_app, init_db
|
||||
app = create_app('$INSTALL_MODE')
|
||||
with app.app_context():
|
||||
init_db()
|
||||
print('✅ Datenbank initialisiert')
|
||||
"
|
||||
|
||||
success_log "Datenbank initialisiert"
|
||||
}
|
||||
|
||||
# Systemd-Service für Produktion erstellen
|
||||
create_systemd_service() {
|
||||
if [ "$INSTALL_MODE" = "production" ]; then
|
||||
log "🔧 Erstelle systemd-Service für Produktion..."
|
||||
|
||||
SERVICE_FILE="/etc/systemd/system/myp-backend.service"
|
||||
|
||||
sudo tee $SERVICE_FILE > /dev/null << EOF
|
||||
[Unit]
|
||||
Description=MYP Backend Flask Application
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=exec
|
||||
User=$USER
|
||||
Group=$USER
|
||||
WorkingDirectory=$SCRIPT_DIR
|
||||
Environment=PATH=$SCRIPT_DIR/venv/bin
|
||||
EnvironmentFile=$SCRIPT_DIR/env.backend
|
||||
ExecStart=$SCRIPT_DIR/venv/bin/gunicorn --bind 0.0.0.0:5000 --workers 4 wsgi:application
|
||||
ExecReload=/bin/kill -s HUP \$MAINPID
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable myp-backend
|
||||
|
||||
success_log "Systemd-Service erstellt: myp-backend.service"
|
||||
log "Starten mit: sudo systemctl start myp-backend"
|
||||
log "Status prüfen mit: sudo systemctl status myp-backend"
|
||||
fi
|
||||
}
|
||||
|
||||
# Hauptinstallation
|
||||
main() {
|
||||
cleanup_existing_installation
|
||||
install_system_dependencies
|
||||
create_virtual_environment
|
||||
install_python_dependencies
|
||||
prepare_configuration
|
||||
initialize_database
|
||||
create_systemd_service
|
||||
|
||||
echo ""
|
||||
echo "========================================"
|
||||
success_log "🎉 Installation erfolgreich abgeschlossen!"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
|
||||
log "Nächste Schritte:"
|
||||
echo ""
|
||||
|
||||
if [ "$INSTALL_MODE" = "production" ]; then
|
||||
echo "📋 Produktionsbetrieb:"
|
||||
echo " 1. Konfiguration prüfen: nano env.backend"
|
||||
echo " 2. Service starten: sudo systemctl start myp-backend"
|
||||
echo " 3. Service prüfen: sudo systemctl status myp-backend"
|
||||
echo " 4. Oder manuell: ./start-production.sh"
|
||||
else
|
||||
log "Erstelle Docker-Konfiguration mit Google DNS..."
|
||||
sudo mkdir -p /etc/docker
|
||||
echo '{
|
||||
"dns": ["8.8.8.8", "8.8.4.4"]
|
||||
}' | sudo tee /etc/docker/daemon.json > /dev/null
|
||||
|
||||
# Docker neu starten, damit die Änderungen wirksam werden
|
||||
if command -v systemctl &>/dev/null; then
|
||||
sudo systemctl restart docker
|
||||
sleep 5
|
||||
elif command -v service &>/dev/null; then
|
||||
sudo service docker restart
|
||||
sleep 5
|
||||
fi
|
||||
echo "🔧 Entwicklungsbetrieb:"
|
||||
echo " 1. Konfiguration prüfen: nano env.backend"
|
||||
echo " 2. Server starten: ./start-backend-server.sh"
|
||||
echo " 3. Development-Server: ./start-backend-server.sh --development"
|
||||
fi
|
||||
|
||||
# Versuche Image explizit mit anderen Tags herunterzuladen
|
||||
log "${YELLOW}Versuche lokal vorhandene Python-Version zu finden...${NC}"
|
||||
echo ""
|
||||
echo "📡 Backend wird verfügbar sein unter:"
|
||||
echo " - API: http://localhost:5000"
|
||||
echo " - Health-Check: http://localhost:5000/health"
|
||||
echo " - Test: http://localhost:5000/api/test"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Suche nach allen verfügbaren Python-Images
|
||||
PYTHON_IMAGES=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep "python:")
|
||||
|
||||
if [ -n "$PYTHON_IMAGES" ]; then
|
||||
log "Gefundene Python-Images: $PYTHON_IMAGES"
|
||||
# Verwende das erste gefundene Python-Image
|
||||
FIRST_PYTHON=$(echo "$PYTHON_IMAGES" | head -n 1)
|
||||
log "${GREEN}Verwende vorhandenes Python-Image: $FIRST_PYTHON${NC}"
|
||||
|
||||
# Aktualisiere den Dockerfile
|
||||
sed -i "s|FROM python:3-slim|FROM $FIRST_PYTHON|g" Dockerfile
|
||||
log "Dockerfile aktualisiert, um lokales Image zu verwenden."
|
||||
else
|
||||
# Versuche unterschiedliche Python-Versionen
|
||||
for PYTHON_VERSION in "python:3.11-slim" "python:3.10-slim" "python:3.9-slim" "python:slim" "python:alpine"; do
|
||||
log "Versuche $PYTHON_VERSION zu laden..."
|
||||
if docker pull $PYTHON_VERSION; then
|
||||
log "${GREEN}Erfolgreich $PYTHON_VERSION heruntergeladen${NC}"
|
||||
# Aktualisiere den Dockerfile
|
||||
sed -i "s|FROM python:3-slim|FROM $PYTHON_VERSION|g" Dockerfile
|
||||
log "Dockerfile aktualisiert, um $PYTHON_VERSION zu verwenden."
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
# Erhöhe Docker-Timeout für langsame Verbindungen und Raspberry Pi
|
||||
export DOCKER_CLIENT_TIMEOUT=300
|
||||
export COMPOSE_HTTP_TIMEOUT=300
|
||||
|
||||
# Verwende die richtige Docker Compose Version
|
||||
if [ "${DOCKER_COMPOSE_V2:-false}" = true ]; then
|
||||
# Docker Compose V2 Plugin (docker compose)
|
||||
log "Baue lokales Image..."
|
||||
if ! docker compose build --no-cache; then
|
||||
error_log "Docker Compose Build (v2) fehlgeschlagen. Versuche mit v1 Format..."
|
||||
if ! docker-compose build --no-cache; then
|
||||
error_log "Docker Compose Build fehlgeschlagen. Siehe Fehlermeldung oben."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
log "Starte Container aus lokalem Image..."
|
||||
if ! docker compose up -d; then
|
||||
error_log "Docker Compose Up (v2) fehlgeschlagen. Versuche mit v1 Format..."
|
||||
if ! docker-compose up -d; then
|
||||
error_log "Docker Compose Up fehlgeschlagen. Siehe Fehlermeldung oben."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# Docker Compose V1 (docker-compose)
|
||||
log "Baue lokales Image..."
|
||||
if ! docker-compose build --no-cache; then
|
||||
error_log "Docker Compose Build fehlgeschlagen. Siehe Fehlermeldung oben."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "Starte Container aus lokalem Image..."
|
||||
if ! docker-compose up -d; then
|
||||
error_log "Docker Compose Up fehlgeschlagen. Siehe Fehlermeldung oben."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Prüfe, ob der Container läuft
|
||||
log "Warte 10 Sekunden, bis der Container gestartet ist..."
|
||||
sleep 10
|
||||
if docker ps | grep -q "myp-backend"; then
|
||||
log "${GREEN}Backend-Container läuft${NC}"
|
||||
else
|
||||
error_log "Backend-Container läuft nicht. Container-Status:"
|
||||
docker ps -a | grep myp-backend
|
||||
log "Container-Logs:"
|
||||
docker logs myp-backend
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test API-Endpunkt
|
||||
log "${YELLOW}Teste Backend-API...${NC}"
|
||||
log "${YELLOW}HINWEIS: Der API-Server ist bei der ersten Installation oft noch nicht erreichbar${NC}"
|
||||
log "${YELLOW}Dies ist ein bekanntes Verhalten wegen der Netzwerkkonfiguration${NC}"
|
||||
log "${YELLOW}Bitte nach der Installation das System neu starten, danach sollte der API-Server erreichbar sein${NC}"
|
||||
|
||||
# Wir versuchen es trotzdem einmal, um zu sehen, ob er vielleicht doch läuft
|
||||
if curl -s http://localhost:5000/health 2>/dev/null | grep -q "healthy"; then
|
||||
log "${GREEN}Backend-API ist erreichbar und funktioniert${NC}"
|
||||
else
|
||||
log "${YELLOW}Backend-API ist wie erwartet noch nicht erreichbar${NC}"
|
||||
log "${GREEN}Das ist völlig normal bei der Erstinstallation${NC}"
|
||||
log "${GREEN}Nach einem Neustart des Systems sollte der API-Server korrekt erreichbar sein${NC}"
|
||||
log "Container-Status prüfen mit: docker logs myp-backend"
|
||||
fi
|
||||
|
||||
# Initialisierung der Datenbank prüfen
|
||||
log "${YELLOW}Prüfe Datenbank-Initialisierung...${NC}"
|
||||
if [ ! -s "instance/myp.db" ]; then
|
||||
log "${YELLOW}Datenbank scheint leer zu sein. Führe Initialisierungsskript aus...${NC}"
|
||||
DB_INIT_OUTPUT=$(docker exec myp-backend python -c "from app import init_db; init_db()" 2>&1)
|
||||
if [ $? -eq 0 ]; then
|
||||
log "${GREEN}Datenbank erfolgreich initialisiert${NC}"
|
||||
else
|
||||
error_log "Fehler bei der Datenbank-Initialisierung:"
|
||||
echo "$DB_INIT_OUTPUT"
|
||||
log "Container-Logs:"
|
||||
docker logs myp-backend
|
||||
fi
|
||||
else
|
||||
log "${GREEN}Datenbank existiert bereits${NC}"
|
||||
fi
|
||||
|
||||
# Teste, ob ein API-Endpunkt Daten zurückgibt
|
||||
log "${YELLOW}Teste Datenbank-Verbindung über API...${NC}"
|
||||
if curl -s http://localhost:5000/api/printers | grep -q "\[\]"; then
|
||||
log "${GREEN}Datenbank-Verbindung funktioniert${NC}"
|
||||
else
|
||||
log "${YELLOW}API gibt keine leere Drucker-Liste zurück. Möglicherweise ist die DB nicht korrekt initialisiert.${NC}"
|
||||
log "API-Antwort:"
|
||||
curl -s http://localhost:5000/api/printers
|
||||
fi
|
||||
|
||||
log "${GREEN}=== Installation abgeschlossen ===${NC}"
|
||||
log "${YELLOW}WICHTIG: Nach der Erstinstallation ist ein Systemneustart erforderlich${NC}"
|
||||
log "${YELLOW}Danach ist das Backend unter http://localhost:5000 erreichbar${NC}"
|
||||
log "Anzeigen der Logs: docker logs -f myp-backend"
|
||||
|
||||
# Verwende die richtige Docker Compose Version für Hinweis
|
||||
if [ "${DOCKER_COMPOSE_V2:-false}" = true ]; then
|
||||
log "Backend stoppen: docker compose -f $BACKEND_DIR/docker-compose.yml down"
|
||||
else
|
||||
log "Backend stoppen: docker-compose -f $BACKEND_DIR/docker-compose.yml down"
|
||||
fi
|
||||
# Installation starten
|
||||
main "$@"
|
1
backend/test-backend-setup.py
Normal file
1
backend/test-backend-setup.py
Normal file
@ -0,0 +1 @@
|
||||
|
@ -1 +1,287 @@
|
||||
# 🏗️ MYP - Separate Server Architektur
|
||||
|
||||
## Übersicht
|
||||
|
||||
Das MYP-System wurde in **zwei vollständig unabhängige Server** aufgeteilt:
|
||||
|
||||
- **🏭 Backend-Server** (Port 5000): Flask-API für Geschäftslogik und Datenmanagement
|
||||
- **🎨 Frontend-Server** (Port 3000): Next.js-Anwendung für Benutzeroberfläche
|
||||
|
||||
## 🔗 Server-Kommunikation
|
||||
|
||||
```
|
||||
┌─────────────────┐ HTTP/API ┌─────────────────┐
|
||||
│ Frontend │◄───────────────►│ Backend │
|
||||
│ (Next.js) │ │ (Flask) │
|
||||
│ Port: 3000 │ │ Port: 5000 │
|
||||
└─────────────────┘ └─────────────────┘
|
||||
```
|
||||
|
||||
## 🚀 Separate Server starten
|
||||
|
||||
### Backend-Server (unabhängig)
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
./start-backend-server.sh
|
||||
|
||||
# Alternative mit Logs
|
||||
./start-backend-server.sh --logs
|
||||
|
||||
# Vollständige Neuinstallation
|
||||
./start-backend-server.sh --clean
|
||||
```
|
||||
|
||||
**Backend verfügbar unter:**
|
||||
|
||||
- 📡 Backend-API: http://localhost:5000
|
||||
- 🔧 Health-Check: http://localhost:5000/health
|
||||
- 📋 API-Docs: http://localhost:5000/swagger
|
||||
|
||||
### Frontend-Server (unabhängig)
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
./start-frontend-server.sh
|
||||
|
||||
# Alternative mit Logs
|
||||
./start-frontend-server.sh --logs
|
||||
|
||||
# Vollständige Neuinstallation
|
||||
./start-frontend-server.sh --clean
|
||||
```
|
||||
|
||||
**Frontend verfügbar unter:**
|
||||
|
||||
- 🌐 Web-App: http://localhost:3000
|
||||
- 🔧 Health-Check: http://localhost:3000/health
|
||||
- 📦 CDN-Assets: http://localhost:8080
|
||||
|
||||
## ⚙️ Konfiguration
|
||||
|
||||
### Backend-Konfiguration
|
||||
|
||||
**Datei:** `backend/env.backend`
|
||||
|
||||
```bash
|
||||
# Backend-Server
|
||||
PORT=5000
|
||||
BACKEND_URL=http://localhost:5000
|
||||
|
||||
# CORS für Frontend-Zugriff
|
||||
CORS_ORIGINS=http://localhost:3000,https://frontend.myp.local
|
||||
|
||||
# Datenbank
|
||||
DATABASE_PATH=instance/myp.db
|
||||
|
||||
# Cache
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PORT=6379
|
||||
```
|
||||
|
||||
### Frontend-Konfiguration
|
||||
|
||||
**Datei:** `frontend/env.frontend`
|
||||
|
||||
```bash
|
||||
# Frontend-Server
|
||||
PORT=3000
|
||||
FRONTEND_URL=http://localhost:3000
|
||||
|
||||
# Backend-API Verbindung
|
||||
BACKEND_API_URL=http://localhost:5000/api
|
||||
NEXT_PUBLIC_API_URL=http://localhost:5000/api
|
||||
|
||||
# Cache
|
||||
FRONTEND_REDIS_PORT=6380
|
||||
```
|
||||
|
||||
## 🐋 Docker-Container
|
||||
|
||||
### Backend-Container
|
||||
|
||||
```bash
|
||||
cd backend
|
||||
docker-compose -f docker-compose.backend.yml up -d
|
||||
|
||||
# Services:
|
||||
# - myp-backend-standalone (Port 5000)
|
||||
# - myp-backend-db (PostgreSQL, Port 5432)
|
||||
# - myp-backend-cache (Redis, Port 6379)
|
||||
```
|
||||
|
||||
### Frontend-Container
|
||||
|
||||
```bash
|
||||
cd frontend
|
||||
docker-compose -f docker-compose.frontend.yml up -d
|
||||
|
||||
# Services:
|
||||
# - myp-frontend-standalone (Port 3000)
|
||||
# - myp-frontend-cache (Redis, Port 6380)
|
||||
# - myp-frontend-cdn (Nginx, Port 8080)
|
||||
```
|
||||
|
||||
## 🔒 Sicherheit
|
||||
|
||||
### CORS-Konfiguration
|
||||
|
||||
Das Backend ist für **explizite Frontend-Origins** konfiguriert:
|
||||
|
||||
```python
|
||||
# Backend: app.py
|
||||
CORS(app,
|
||||
origins=['http://localhost:3000', 'https://frontend.myp.local'],
|
||||
supports_credentials=True,
|
||||
allow_headers=['Content-Type', 'Authorization', 'X-Requested-With'],
|
||||
methods=['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'])
|
||||
```
|
||||
|
||||
### API-Authentifizierung
|
||||
|
||||
- **JWT-Tokens** für API-Zugriff
|
||||
- **Session-basierte** Authentifizierung für Web-UI
|
||||
- **Separate Secrets** für Frontend und Backend
|
||||
|
||||
## 📊 Monitoring
|
||||
|
||||
### Health-Checks
|
||||
|
||||
**Backend:** GET http://localhost:5000/health
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "healthy",
|
||||
"service": "myp-backend",
|
||||
"database": "connected",
|
||||
"timestamp": "2024-01-15T10:30:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
**Frontend:** GET http://localhost:3000/health
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "healthy",
|
||||
"service": "myp-frontend",
|
||||
"backend": {
|
||||
"url": "http://localhost:5000",
|
||||
"status": "connected"
|
||||
},
|
||||
"timestamp": "2024-01-15T10:30:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Logs verfolgen
|
||||
|
||||
```bash
|
||||
# Backend-Logs
|
||||
cd backend
|
||||
docker-compose -f docker-compose.backend.yml logs -f
|
||||
|
||||
# Frontend-Logs
|
||||
cd frontend
|
||||
docker-compose -f docker-compose.frontend.yml logs -f
|
||||
```
|
||||
|
||||
## 🔧 Troubleshooting
|
||||
|
||||
### Backend startet nicht
|
||||
|
||||
```bash
|
||||
# 1. Prüfe Ports
|
||||
netstat -an | grep 5000
|
||||
|
||||
# 2. Prüfe Backend-Logs
|
||||
cd backend
|
||||
docker-compose -f docker-compose.backend.yml logs backend
|
||||
|
||||
# 3. Datenbank-Migration
|
||||
docker-compose -f docker-compose.backend.yml exec backend flask db upgrade
|
||||
```
|
||||
|
||||
### Frontend kann Backend nicht erreichen
|
||||
|
||||
```bash
|
||||
# 1. Prüfe Backend-Verfügbarkeit
|
||||
curl http://localhost:5000/health
|
||||
|
||||
# 2. Prüfe CORS-Konfiguration
|
||||
curl -H "Origin: http://localhost:3000" \
|
||||
-H "Access-Control-Request-Method: GET" \
|
||||
-H "Access-Control-Request-Headers: Content-Type" \
|
||||
-X OPTIONS http://localhost:5000/api/printers
|
||||
|
||||
# 3. Prüfe Frontend-Umgebungsvariablen
|
||||
cd frontend
|
||||
grep BACKEND env.frontend
|
||||
```
|
||||
|
||||
### Port-Konflikte
|
||||
|
||||
```bash
|
||||
# Standard-Ports ändern
|
||||
# Backend: PORT=5001 in env.backend
|
||||
# Frontend: PORT=3001 in env.frontend
|
||||
|
||||
# Neue URLs in beiden Konfigurationen anpassen
|
||||
```
|
||||
|
||||
## 🌐 Deployment
|
||||
|
||||
### Produktions-Deployment
|
||||
|
||||
```bash
|
||||
# Backend (Server 1)
|
||||
cd backend
|
||||
FLASK_ENV=production ./start-backend-server.sh
|
||||
|
||||
# Frontend (Server 2)
|
||||
cd frontend
|
||||
NODE_ENV=production BACKEND_API_URL=https://api.myp.de ./start-frontend-server.sh
|
||||
```
|
||||
|
||||
### Reverse Proxy (Optional)
|
||||
|
||||
Für Produktion können beide Server hinter einem Reverse Proxy laufen:
|
||||
|
||||
```
|
||||
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
||||
│ Client │────►│ Nginx/Caddy │────►│ Frontend │
|
||||
│ │ │ │ ┌─►│ :3000 │
|
||||
└─────────────┘ │ /api/* ─────┤──┘ └─────────────┘
|
||||
│ │ ┌─►┌─────────────┐
|
||||
│ /api/* ─────┤──┘ │ Backend │
|
||||
└─────────────┘ │ :5000 │
|
||||
└─────────────┘
|
||||
```
|
||||
|
||||
## 📁 Dateistruktur
|
||||
|
||||
```
|
||||
Projektarbeit-MYP/
|
||||
├── backend/ # 🏭 Backend-Server
|
||||
│ ├── docker-compose.backend.yml # Docker-Konfiguration
|
||||
│ ├── start-backend-server.sh # Start-Skript
|
||||
│ ├── env.backend # Umgebungsvariablen
|
||||
│ └── app.py # Flask-Anwendung
|
||||
├── frontend/ # 🎨 Frontend-Server
|
||||
│ ├── docker-compose.frontend.yml # Docker-Konfiguration
|
||||
│ ├── start-frontend-server.sh # Start-Skript
|
||||
│ ├── env.frontend # Umgebungsvariablen
|
||||
│ └── src/ # Next.js-Anwendung
|
||||
└── SEPARATE_SERVERS_GUIDE.md # Diese Dokumentation
|
||||
```
|
||||
|
||||
## ✅ Vorteile der Trennung
|
||||
|
||||
1. **🔄 Unabhängige Skalierung** - Frontend und Backend können getrennt skaliert werden
|
||||
2. **🚀 Separate Deployments** - Updates können unabhängig deployed werden
|
||||
3. **🛡️ Verbesserte Sicherheit** - Klare API-Grenzen und CORS-Kontrolle
|
||||
4. **🔧 Technologie-Flexibilität** - Frontend und Backend können verschiedene Technologien verwenden
|
||||
5. **📊 Besseres Monitoring** - Separate Health-Checks und Logs
|
||||
6. **🏗️ Microservice-Ready** - Vorbereitung für Microservice-Architektur
|
||||
|
||||
---
|
||||
|
||||
**Hinweis:** Die alte gekoppelte Konfiguration ist weiterhin in `docker-compose.yml` verfügbar, wird aber für neue Deployments nicht empfohlen.
|
||||
|
Loading…
x
Reference in New Issue
Block a user