Nginx Reverse Proxy¶
Ziel¶
Diese Seite erklärt, wie Nginx als Reverse Proxy eingerichtet wird, um öffentliche Domains und Subdomains an lokale Docker-Dienste weiterzuleiten.
Die Anleitung ist allgemein verwendbar. Immohai dient als konkretes Praxisbeispiel.
Grundprinzip¶
Nginx nimmt öffentliche HTTP- und HTTPS-Anfragen entgegen.
Danach leitet Nginx die Anfrage intern an den passenden lokalen Dienst weiter.
Browser
↓
Domain oder Subdomain
↓
Nginx
↓
proxy_pass
↓
127.0.0.1:<lokaler-port>
↓
Docker-Container
Beispiel:
playbook.example.com → 127.0.0.1:8100
app1.example.com → 127.0.0.1:8200
docs.app1.example.com → 127.0.0.1:8201
Warum Nginx als Reverse Proxy?¶
| Vorteil | Bedeutung |
|---|---|
| zentrale öffentliche Ports | Nginx belegt 80 und 443 |
| mehrere Apps auf einem Server | Routing erfolgt über Subdomains |
| Docker-Dienste bleiben lokal | Container sind nicht direkt öffentlich erreichbar |
| HTTPS zentral möglich | Certbot kann Nginx automatisch konfigurieren |
| klare Wartung | jede Subdomain hat eine eigene Konfigurationsdatei |
Nginx installieren¶
sudo apt update
sudo apt install nginx -y
Status prüfen:
sudo systemctl status nginx
Nginx starten:
sudo systemctl start nginx
Nginx beim Booten automatisch starten:
sudo systemctl enable nginx
Prüfen, ob Nginx auf Port 80 hört¶
sudo ss -ltnp | grep ':80'
Erwartung:
LISTEN ... 0.0.0.0:80 ... nginx
LISTEN ... [::]:80 ... nginx
Port-80-Konflikt lösen¶
Beim Start von Nginx kann folgende Fehlermeldung auftreten:
bind() to 0.0.0.0:80 failed (98: Address already in use)
Das bedeutet:
Port 80 ist bereits belegt.
Typische Ursache:
Ein Docker-Container läuft direkt auf 0.0.0.0:80.
Prüfen:
sudo ss -ltnp | grep ':80'
docker ps --format "table {{.Names}}\t{{.Ports}}"
Lösung:
- Container auf lokalen Port umstellen.
- Alternativ alten Container stoppen und entfernen, wenn er nicht mehr gebraucht wird.
Beispiel:
docker stop <container-name>
docker rm <container-name>
Danach Nginx erneut starten:
sudo systemctl start nginx
sudo systemctl status nginx
Nginx-Dateistruktur¶
Nginx verwendet unter Ubuntu typischerweise diese Struktur:
/etc/nginx/sites-available/
Hier liegen vorbereitete Konfigurationsdateien.
/etc/nginx/sites-enabled/
Hier liegen symbolische Links auf aktive Konfigurationen.
Eine Seite wird aktiviert mit:
sudo ln -s /etc/nginx/sites-available/app.example.com /etc/nginx/sites-enabled/
Allgemeines Server-Block-Muster¶
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://127.0.0.1:8200;
proxy_http_version 1.1;
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;
}
}
Wichtige Stellen:
| Zeile | Bedeutung |
|---|---|
listen 80; |
Nginx nimmt HTTP-Anfragen an |
server_name app.example.com; |
Domain oder Subdomain für diesen Block |
proxy_pass http://127.0.0.1:8200; |
lokaler Zielport des Docker-Dienstes |
proxy_set_header ... |
Weitergabe wichtiger Request-Informationen |
Praxisbeispiel Developer Playbook¶
Datei erstellen:
sudo nano /etc/nginx/sites-available/playbook.ohaisoft.com
Inhalt:
server {
listen 80;
server_name playbook.ohaisoft.com;
location / {
proxy_pass http://127.0.0.1:8100;
proxy_http_version 1.1;
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;
}
}
Aktivieren:
sudo ln -s /etc/nginx/sites-available/playbook.ohaisoft.com /etc/nginx/sites-enabled/
Praxisbeispiel Immohai App¶
Datei erstellen:
sudo nano /etc/nginx/sites-available/immohai.ohaisoft.com
Inhalt:
server {
listen 80;
server_name immohai.ohaisoft.com;
location / {
proxy_pass http://127.0.0.1:8200;
proxy_http_version 1.1;
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;
}
}
Aktivieren:
sudo ln -s /etc/nginx/sites-available/immohai.ohaisoft.com /etc/nginx/sites-enabled/
Praxisbeispiel Immohai Dokumentation¶
Datei erstellen:
sudo nano /etc/nginx/sites-available/docs.immohai.ohaisoft.com
Inhalt:
server {
listen 80;
server_name docs.immohai.ohaisoft.com;
location / {
proxy_pass http://127.0.0.1:8201;
proxy_http_version 1.1;
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;
}
}
Aktivieren:
sudo ln -s /etc/nginx/sites-available/docs.immohai.ohaisoft.com /etc/nginx/sites-enabled/
Nginx-Konfiguration prüfen¶
Nach jeder Änderung:
sudo nginx -t
Erwartung:
syntax is ok
test is successful
Danach Nginx neu laden:
sudo systemctl reload nginx
HTTP testen¶
curl -I http://playbook.ohaisoft.com
curl -I http://immohai.ohaisoft.com
curl -I http://docs.immohai.ohaisoft.com
Erwartung vor HTTPS-Einrichtung:
HTTP/1.1 200 OK
Nach HTTPS-Einrichtung kann stattdessen eine Weiterleitung erscheinen:
HTTP/1.1 301 Moved Permanently
Firewall prüfen¶
sudo ufw status verbose
Erwartung:
OpenSSH ALLOW IN
Nginx Full ALLOW IN
oder:
22/tcp ALLOW IN
80,443/tcp ALLOW IN
Falls HTTP und HTTPS noch nicht freigegeben sind:
sudo ufw allow 'Nginx Full'
sudo ufw reload
Praxisbeispiel Immohai¶
Aktuelle Nginx-Weiterleitungen:
playbook.ohaisoft.com → 127.0.0.1:8100
immohai.ohaisoft.com → 127.0.0.1:8200
docs.immohai.ohaisoft.com → 127.0.0.1:8201
Im Praxisbeispiel war ein alter Container aktiv:
atlas-web 0.0.0.0:80->80/tcp
Dieser Container blockierte Nginx.
Lösung:
docker stop atlas-web
docker rm atlas-web
Danach konnte Nginx Port 80 übernehmen.
Best Practices¶
- Für jede Subdomain eine eigene Datei unter
sites-availableverwenden. - Nur aktive Seiten nach
sites-enabledverlinken. - Nach jeder Änderung
sudo nginx -tausführen. - Erst nach erfolgreichem Test
sudo systemctl reload nginxausführen. - Docker-Dienste nur lokal auf
127.0.0.1binden. - Nginx-Konfigurationen ohne Secrets dokumentieren.
- HTTPS anschließend mit Certbot einrichten.
Typische Fehler¶
| Fehler | Ursache | Lösung |
|---|---|---|
| Nginx startet nicht | Port 80 ist belegt |
sudo ss -ltnp \| grep ':80' |
| Subdomain zeigt falschen Inhalt | falscher server_name |
Nginx-Datei prüfen |
| App ist nicht erreichbar | falscher proxy_pass |
lokalen Port prüfen |
nginx -t schlägt fehl |
Syntaxfehler | Fehlermeldung lesen und Datei korrigieren |
| Änderung wird nicht sichtbar | Nginx wurde nicht neu geladen | sudo systemctl reload nginx |
| Certbot findet Domain nicht | DNS zeigt nicht auf Server | DNS mit nslookup prüfen |
Checkliste¶
- [ ] Nginx installiert
- [ ] Nginx läuft
- [ ] Port
80ist frei - [ ] Docker-Container belegen nicht öffentlich Port
80 - [ ] Nginx-Datei für App erstellt
- [ ] Nginx-Datei für Dokumentation erstellt
- [ ] Nginx-Datei für Playbook erstellt, falls benötigt
- [ ] Dateien nach
sites-enabledverlinkt - [ ]
sudo nginx -terfolgreich - [ ] Nginx neu geladen
- [ ] HTTP öffentlich getestet
- [ ] Firewall erlaubt
Nginx Full