Zum Inhalt

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-available verwenden.
  • Nur aktive Seiten nach sites-enabled verlinken.
  • Nach jeder Änderung sudo nginx -t ausführen.
  • Erst nach erfolgreichem Test sudo systemctl reload nginx ausführen.
  • Docker-Dienste nur lokal auf 127.0.0.1 binden.
  • 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 80 ist 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-enabled verlinkt
  • [ ] sudo nginx -t erfolgreich
  • [ ] Nginx neu geladen
  • [ ] HTTP öffentlich getestet
  • [ ] Firewall erlaubt Nginx Full