init at work

This commit is contained in:
Mathias Schneider
2026-03-27 12:58:01 +01:00
parent 352c352056
commit 8d40597732
60 changed files with 16498 additions and 0 deletions
+430
View File
@@ -0,0 +1,430 @@
## 1. Grundidee: Was ist nginx gerade im PythonKontext?
nginx („engine x“) ist ein **Webserver** und **Reverse Proxy**, der:
- HTTP(S)-Anfragen aus dem Internet annimmt
- statische Dateien (HTML, CSS, Bilder, JS) direkt ausliefert
- Anfragen für **dynamische Inhalte** (z.B. deine PythonApp) an einen **Anwendungsserver** weiterleitet (z.B. Gunicorn, uWSGI, [[uvicorn]])
Im PythonKontext wird nginx fast immer als **„Vorderseite“ (Frontend) vor einer PythonWebanwendung** eingesetzt.
Typischer Aufbau:
```text
Browser des Nutzers -> nginx -> Gunicorn/uWSGI/uvicorn -> Python-App (Django, Flask, FastAPI, ...)
(Port 80/443) (lokaler Port, z.B. 8000)
```
---
## 2. Einordnung in die Webwelt: Grundbegriffe
Damit nginx einzuordnen ist, müssen ein paar Begriffe klar sein:
### 2.1 Webserver
Ein **Webserver**:
- läuft auf einem Rechner (Server)
- „lauscht“ auf Port 80 (HTTP) oder 443 (HTTPS)
- nimmt HTTP-Anfragen entgegen und schickt HTTP-Antworten zurück
Beispiele:
- **nginx**
- **Apache HTTP Server**
- (leichtere) Caddy, lighttpd
### 2.2 Application Server / WSGI-/ASGI-Server
Ein **Application Server** führt deine **Web-App** aus, also deinen Python-Code.
- Für klassische synchronen Python-Webapps: **WSGI**-Server
- z.B. **[[Gunicorn]]**, **uWSGI**, mod_wsgi
- Für moderne, asynchrone Apps: **ASGI**-Server
- z.B. **[[uvicorn]]**, **[[hypercorn]]**, Daphne
Der App-Server:
- spricht mit deinem Python-Framework (Django, Flask, [[FastAPI]], etc.)
- versteht Anfragen im WSGI/ASGI-Format
- erzeugt dynamische Antworten (z.B. JSON, HTML aus Templates)
### 2.3 Python-Webframework (Django, Flask, [[FastAPI]] …)
Ein **Framework** ist deine Programmierbibliothek, mit der du die Web-App baust:
- Django: „Vollausstattung“ (ORM, Admin, Auth, etc.)
- Flask: minimaler Kern, viel per Erweiterung
- [[FastAPI]]: modern, async, stark bei APIs
**Das Framework ist nicht der Webserver.**
Es definiert nur, wie dein Code auf Anfragen reagieren soll.
---
## 3. Abgrenzung: nginx vs. verwandte Begriffe
### 3.1 nginx vs. Apache
Beide sind **Webserver**, Unterschiede grob:
- **nginx**
- schnell bei vielen gleichzeitigen Verbindungen
- ressourcensparend (eventbasiert)
- sehr gut als Reverse Proxy, Load Balancer, TLS-Terminator
- **Apache**
- älter, sehr weit verbreitet
- modulbasiert, viel Legacy
- kann PHP & Co. direkt ausführen (mod_php, etc.)
Im modernen Python-Umfeld: **nginx + Gunicorn/[[uvicorn]]** ist ein sehr gängiges Setup.
### 3.2 nginx vs. [[Gunicorn]]/uWSGI/[[uvicorn]]
- **nginx**: Webserver / Reverse Proxy
- **[[Gunicorn]]/uWSGI/[[uvicorn]]**: Python-Application-Server
nginx:
- kümmert sich um HTTP(S), TLS, statische Dateien, Load Balancing
- schickt Anfragen an den Application-Server weiter
[[Gunicorn]]/[[uvicorn]]:
- startet deine Python-App
- verarbeitet die Anfragen logikseitig
- rendert Templates, greift auf Datenbanken zu, etc.
### 3.3 nginx vs. Django/Flask/[[FastAPI]]
- nginx: Infrastruktur-Komponente (Server)
- Django/Flask/[[FastAPI]]: Bibliotheken, mit denen du deinen Code schreibst
Eine typische Kombi:
```text
nginx + Gunicorn + Django
nginx + uvicorn + FastAPI
nginx + uWSGI + Flask
```
Jede Komponente hat ihren klaren Aufgabenbereich.
---
## 4. Welche Probleme löst nginx im Python-Setup?
### 4.1 Sichere und stabile Auslieferung deiner Python-Webapp
Problem:
Die eingebaute Entwicklungsserver in Django/Flask sind nur für **lokale Entwicklung** gedacht:
- wenig performant
- kaum Sicherheitsfeatures
- nicht für viele gleichzeitige Nutzer ausgelegt
Lösung:
nginx + App-Server (Gunicorn/uvicorn):
- nginx nimmt alle Anfragen entgegen
- Python-App läuft hinter nginx auf einem internen Port
- Anwendung ist stabiler, sicherer, skalierbarer
### 4.2 Auslieferung statischer Dateien
Problem:
Python-Frameworks sind nicht optimiert, um Millionen von statischen Dateien schnell auszuliefern.
Lösung:
- nginx kann statische Dateien extrem effizient ausliefern
- Python-App wird entlastet
**Beispiel:** Django-Setup:
```text
Browser -> nginx -> (statische Dateien: /static/) direkt von nginx
-> (dynamische URLs: /api/, /admin/) an Gunicorn/Django
```
### 4.3 HTTPS / TLS-Termination
Problem:
Du willst deine Seite unter **https://deinedomain.de** mit Zertifikat ausliefern.
Python-Application-Server kümmern sich eher nicht um Zertifikate.
Lösung:
- nginx bietet HTTPS/TLS an (inkl. Lets Encrypt-Integration)
- entschlüsselt eingehende Anfragen
- leitet sie dann intern als HTTP an Gunicorn/uvicorn weiter
So muss sich deine Python-App nicht um Zertifikate kümmern.
### 4.4 Load Balancing (Lastverteilung)
Problem:
Eine einzelne Instanz deiner Python-App reicht nicht bei hoher Last.
Lösung:
- nginx kann Anfragen auf mehrere App-Server verteilen:
```text
Browser -> nginx -> Gunicorn Instanz 1
-> Gunicorn Instanz 2
-> Gunicorn Instanz 3
```
Damit erreichst du höhere Verfügbarkeit und Kapazität.
### 4.5 Reverse Proxy / Schutz der App
Problem:
Du willst deine App nicht direkt ins Internet hängen (Sicherheitsrisiko, private Ports).
Lösung:
- nginx steht „davor“ und leitet nur definierte Anfragen durch
- interne Ports (z.B. 8000) sind von außen nicht erreichbar
- nginx kann zusätzliche Security-Header, Ratelimits, IP-Filter etc. einsetzen
---
## 5. Herausforderungen bei der Arbeit mit nginx
### 5.1 Konfigurationssyntax & -struktur
- nginx wird über Textdateien konfiguriert (z.B. `/etc/nginx/nginx.conf` und `sites-available/...`)
- die Syntax ist am Anfang ungewohnt:
- `http`, `server`, `location`, `upstream`, `listen`, etc.
- Fehler in der Konfiguration führen dazu, dass nginx nicht startet oder falsch weiterleitet
Praxis-Hinweise:
```bash
sudo nginx -t # Konfiguration testen
sudo systemctl reload nginx # Konfiguration neu laden
```
### 5.2 Rechte & Pfade (Linux-Dateisystem)
Probleme:
- nginx läuft als bestimmter Benutzer (z.B. `www-data`)
- Python-App läuft evtl. als anderer Benutzer (z.B. `myapp`)
- Zugriffsrechte auf Dateien/Ordner (Logs, statische Dateien) müssen passen
Beispiel:
Wenn statische Dateien unter `/var/www/myapp/static/` liegen, muss der nginx-User Lesezugriff haben.
### 5.3 Fehlersuche (Debugging)
- Fehler können an mehreren Stellen auftreten:
- DNS / Domain falsch
- nginx-Konfiguration fehlerhaft
- App-Server (Gunicorn/uvicorn) läuft nicht
- Python-App wirft Fehler
Praxis-Tipp:
- in nginx-Logs schauen:
- `/var/log/nginx/access.log`
- `/var/log/nginx/error.log`
- in App-Logs schauen
- Ports prüfen: `ss -tulpen` oder `netstat -tulpen`
### 5.4 Performance-Tuning
Fortgeschrittener, aber wichtig bei größerem Traffic:
- wie viele Worker-Prozesse nginx nutzt
- Keep-Alive-Einstellungen
- Buffergrößen
- Cache-Konfiguration für statische Inhalte
Am Anfang reicht meist die Standardkonfiguration, später optimiert man bei Bedarf.
---
## 6. Praxisnahe Beispiele
### 6.1 Minimalbeispiel: Flask-App hinter nginx + Gunicorn
**1. Eine einfache Flask-App (Python)**
Datei: `app.py`
```python
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return "Hallo, Welt! Das kommt aus Flask hinter nginx."
```
Start des App-Servers (Gunicorn):
```bash
pip install flask gunicorn
gunicorn -w 3 -b 127.0.0.1:8000 app:app
# -w 3: 3 Worker
# -b 127.0.0.1:8000: lauscht auf Port 8000 nur lokal
```
**2. nginx-Konfiguration (vereinfacht)**
Datei: z.B. `/etc/nginx/sites-available/myflaskapp`:
```nginx
server {
listen 80;
server_name example.com; # deine Domain oder IP
# Statische Dateien (wenn du welche hast)
# root /var/www/myflaskapp; # falls du HTML/Assets direkt ablegen willst
location / {
proxy_pass http://127.0.0.1:8000; # Gunicorn
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
Dann:
```bash
sudo ln -s /etc/nginx/sites-available/myflaskapp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
```
Ablauf:
1. Browser ruft `http://example.com/` auf
2. nginx nimmt Anfrage auf Port 80 entgegen
3. nginx leitet an `http://127.0.0.1:8000` weiter (Gunicorn/Flask)
4. Flask antwortet mit „Hallo, Welt“
5. nginx sendet diese Antwort an den Browser zurück
### 6.2 Beispiel: Django mit statischen Dateien
**1. Django-Setup (stark vereinfacht)**
In `settings.py`:
```python
STATIC_URL = "/static/"
STATIC_ROOT = "/var/www/mydjangoproject/static/"
```
Danach statische Dateien sammeln:
```bash
python manage.py collectstatic
```
**2. nginx-Konfiguration (Ausschnitt)**
```nginx
server {
listen 80;
server_name example.com;
# Statische Dateien direkt von nginx
location /static/ {
alias /var/www/mydjangoproject/static/;
access_log off;
expires 30d;
}
# Alles andere an Django via Gunicorn
location / {
proxy_pass http://127.0.0.1:8001; # hier läuft Gunicorn
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
Vorteil:
- statische Inhalte kommen extrem schnell von nginx
- Django/Gunicorn verarbeitet nur „echte“ App-Logik
### 6.3 Beispiel: HTTPS mit Lets Encrypt (Konzept)
Mit Tools wie **certbot** kannst du für nginx kostenlos TLS-Zertifikate holen.
Grobe Schritte:
```bash
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com
```
certbot:
- holt Zertifikat
- passt nginx-Konfiguration an (Port 443, SSL-Parameter)
- richtet automatische Erneuerung ein
nginx-Konfiguration enthält danach z.B.:
```nginx
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8000;
...
}
}
```
Damit ist deine Python-App per HTTPS erreichbar.
---
## 7. Zusammenfassung
- **nginx** ist ein leistungsfähiger Webserver und Reverse Proxy, der im Python-Kontext typischerweise:
- vor deiner Python-Webanwendung sitzt
- HTTP(S) abwickelt
- statische Dateien effizient ausliefert
- Anfragen an einen Python-Application-Server (Gunicorn, uWSGI, uvicorn) weiterleitet
- TLS/HTTPS, Load Balancing, Security-Features bereitstellt
- **Abgrenzung**:
- nginx ≠ Python-Framework (Django/Flask/[[FastAPI]])
- nginx ≠ Application-Server (Gunicorn/uvicorn)
- nginx = Webserver/Reverse Proxy
- **Gelöste Probleme**:
- sichere Produktion anstelle von Entwicklungsservern
- Performance für statische Inhalte
- TLS/HTTPS, Lastverteilung, Schutz der App
- **Herausforderungen**:
- Konfigurationsdateien verstehen
- Rechte & Pfade korrekt setzen
- Fehler systematisch debuggen
- bei hoher Last Performance tunen