tesm.service startete die App bisher direkt per 'python3 app.py', was Flasks eingebauten Werkzeug-Entwicklungsserver nutzt -- der meldet bei jedem Start 'WARNING: This is a development server. Do not use it in a production deployment.' und ist bewusst nicht für Dauerbetrieb gebaut. Umgestellt auf Gunicorn, mit zwei bewusst gesetzten Einschraenkungen: - '--workers 1': die App haelt laufende Wartungs-Jobs/Import-Vorschauen nur im Arbeitsspeicher DES EINEN Prozesses (_maintenance_jobs, _pending_imports, ...) -- mehrere Worker-Prozesse wuerden diesen Zustand auf mehrere, sich nicht kennende Prozesse verteilen. - '--worker-class gthread --threads 16' statt eines async-Workers: das Browser-SSH-Terminal (flask-sock) belegt pro offener WebSocket- Verbindung einen blockierenden Thread. - '--timeout 0': deaktiviert Gunicorns eigenen 30s-Worker-Timeout, der sonst auch eine offene, aber gerade inaktive SSH-Terminal-Verbindung killen wuerde. Live auf POETEST verifiziert: keine WARNING-Zeile mehr, genau 1 Master- + 1 Worker-Prozess, alle Kernseiten weiterhin 200, und als kritischer Regressionstest das WebSocket-SSH-Terminal Ende-zu-Ende gegen einen echten Host erfolgreich getestet (Host-Key/Passwort-Prompt/Login/Shell). Dabei einen unabhaengigen Altlast-Fehler in POETESTs venv gefunden und allgemein in install.sh gefixt: './venv/bin/pip' hat eine zur Venv-Erstellung fest einprogrammierte Shebang-Zeile -- nach der historischen Umbenennung 'poe_manager' -> 'tesm' zeigte sie auf einen nicht mehr existierenden Pfad und schlug mit 'cannot execute: required file not found' fehl. 'python3 -m pip' umgeht das, da nur der (korrekt referenzierte) venv-Python-Interpreter selbst gebraucht wird -- betrifft sonst auch jedes kuenftige In-Place-Update auf einem aehnlich gewachsenen Host.
24 lines
849 B
Desktop File
24 lines
849 B
Desktop File
[Unit]
|
|
Description=TESM Web App
|
|
After=network.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=root
|
|
WorkingDirectory=/srv/tesm
|
|
# Produktiver WSGI-Server (gunicorn) statt Flasks eigenem app.run()-
|
|
# Entwicklungsserver -- siehe requirements.txt für die ausführliche
|
|
# Begründung von "--workers 1" (In-Memory-Zustand) und "--worker-class
|
|
# gthread" (blockierende WebSocket-Threads für das Browser-SSH-Terminal).
|
|
# "--timeout 0" deaktiviert Gunicorns Worker-Timeout: der greift sonst
|
|
# nach 30s auch bei einer offenen, aber gerade inaktiven SSH-Terminal-
|
|
# WebSocket-Verbindung und würde den Worker (und damit JEDE Verbindung,
|
|
# da nur ein Prozess läuft) killen.
|
|
ExecStart=/srv/tesm/venv/bin/gunicorn --workers 1 --worker-class gthread --threads 16 \
|
|
--timeout 0 --bind 0.0.0.0:5000 app:app
|
|
Restart=always
|
|
RestartSec=5
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|