Ein Reverse Proxy nimmt öffentlichen Verkehr auf den Ports 80 und 443 entgegen und leitet ihn an Anwendungen weiter, die nur lokal lauschen. Er liefert HTTPS, mehrere Websites auf einer IP und eine zentrale Stelle für Logs und Limits. Diese Anleitung richtet ihn auf einem VPS Linux Infrawire für Node.js-, Python- oder Docker-Apps ein.
📋 Voraussetzungen
- Ein Linux-VPS (Ubuntu 24.04 / Debian 12 oder AlmaLinux 9 / Rocky 9) mit SSH-Root-Zugang. IP und Root-Passwort stehen in Ihrem Kundenbereich.
- Eine Domain
example.commit A/AAAA-Einträgen aufVPS_IP. - Eine Anwendung, die auf einem lokalen Port lauscht, zum Beispiel
127.0.0.1:3000.
📦 Nginx installieren
Bash# Debian / Ubuntu sudo apt update && sudo apt install -y nginx # AlmaLinux / Rocky sudo dnf install -y nginx sudo systemctl enable --now nginx
Unter AlmaLinux/Rocky verbietet SELinux Nginx standardmäßig Verbindungen zu Backends. Erlauben Sie es einmalig:
Bashsudo setsebool -P httpd_can_network_connect 1
🚀 Eine erste Anwendung hinter dem Proxy
Ihre App muss auf 127.0.0.1 lauschen, nicht auf 0.0.0.0, damit sie nur über Nginx erreichbar ist. Unabhängig von der Sprache ist das Muster gleich: node server.js auf Port 3000, gunicorn -b 127.0.0.1:8000 app:app für Python oder ein Container, veröffentlicht mit docker run -d -p 127.0.0.1:3000:80 IMAGE.
Erstellen Sie /etc/nginx/sites-available/example.com (unter AlmaLinux/Rocky /etc/nginx/conf.d/example.com.conf):
Nginx1server { 2 listen 80; 3 listen [::]:80; 4 server_name example.com; 5 6 location / { 7 proxy_pass http://127.0.0.1:3000; 8 proxy_http_version 1.1; 9 proxy_set_header Host $host; 10 proxy_set_header X-Real-IP $remote_addr; 11 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 12 proxy_set_header X-Forwarded-Proto $scheme; 13 } 14}
Aktivieren Sie sie unter Debian/Ubuntu, prüfen und laden Sie neu:
Bashsudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx
Die X-Forwarded-*-Header teilen der Anwendung die echte Client-IP mit und ob der Besucher HTTPS nutzte. Ohne sie sieht Ihre App nur 127.0.0.1 und erzeugt womöglich http://-Links. Viele Frameworks müssen zudem angewiesen werden, dem Proxy zu vertrauen (zum Beispiel app.set('trust proxy', 1) in Express).
🔌 WebSocket-Unterstützung
WebSocket braucht die HTTP-Upgrade-Header. Fügen Sie oben im http-Kontext eine map ein (zum Beispiel in /etc/nginx/conf.d/websocket.conf):
Nginxmap $http_upgrade $connection_upgrade { default upgrade; '' close; }
Dann im location-Block:
Nginxproxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade;
⏱️ Timeouts und Body-Größe
Standard sind 60 Sekunden und 1 MB. Passen Sie sie für langsame Endpunkte oder Uploads an:
Nginxproxy_connect_timeout 5s; proxy_read_timeout 120s; proxy_send_timeout 120s; client_max_body_size 50m;
Für langlebige WebSockets erhöhen Sie proxy_read_timeout (zum Beispiel 3600s) oder lassen die Anwendung Pings senden.
🔒 HTTPS mit Certbot
Öffnen Sie zuerst die Firewall für 80 und 443, dann:
Bash# Debian / Ubuntu sudo apt install -y certbot python3-certbot-nginx sudo certbot --nginx -d example.com
Unter AlmaLinux/Rocky installieren Sie Certbot mit sudo dnf install -y epel-release und danach sudo dnf install -y certbot python3-certbot-nginx. Certbot trägt das Zertifikat in Ihren Server-Block ein, bietet die Weiterleitung von HTTP auf HTTPS an und richtet die automatische Erneuerung ein. Prüfen Sie sie mit:
Bashsudo certbot renew --dry-run
🗂️ Mehrere Apps auf einem VPS
Legen Sie pro Domain einen Server-Block an, jeweils mit eigenem server_name und eigenem lokalen Port:
Nginx1server { 2 listen 80; 3 server_name app1.example.com; 4 location / { proxy_pass http://127.0.0.1:3000; } 5} 6 7server { 8 listen 80; 9 server_name app2.example.com; 10 location / { proxy_pass http://127.0.0.1:8000; } 11}
Wiederholen Sie die Proxy-Header in jedem Block und starten Sie Certbot mit -d app1.example.com -d app2.example.com. Sie können auch nach Pfad trennen (location /api/ { proxy_pass http://127.0.0.1:8000/; }); der abschließende Schrägstrich entfernt dann das Präfix.
✅ Testen
Bashcurl -I https://example.com ss -ltnp | grep -E ':(80|443|3000)' sudo tail -f /var/log/nginx/error.log
Der Backend-Port sollte nur an 127.0.0.1 gebunden sein, während Nginx auf 80 und 443 lauscht.
🛠️ Fehlerbehebung
502 Bad Gateway. Die App ist gestoppt oder läuft auf einem anderen Port. Prüfen Sie mit ss -ltnp und starten Sie sie. Unter AlmaLinux/Rocky bedeutet ein Permission denied im Fehlerlog, dass der SELinux-Boolean von oben fehlt.
504 Gateway Timeout. Das Backend braucht länger als proxy_read_timeout. Erhöhen Sie den Wert oder optimieren Sie den Endpunkt.
WebSocket bricht ab oder scheitert mit 400/426. Die Header Upgrade und Connection fehlen, oder proxy_http_version 1.1; ist nicht gesetzt.
Falsche Client-IP in den Logs. X-Forwarded-For wird gesendet, aber Ihre App vertraut dem Proxy nicht. Aktivieren Sie die Vertrauenseinstellung Ihres Frameworks.
🎉 Ihre Anwendungen laufen jetzt hinter Nginx mit HTTPS, sauberen Headern und Platz für so viele Websites, wie Ihr VPS verkraftet.