Nginx Docker Reverse Proxy wirft 404 Fehler ab dem zweiten Request

Als großer Fan von “nackten Servern” auf denen nur Docker Container laufen, nutze ich Nginx als Reverse Proxy – im Speziellen das großartige Setup von jwilder/nginx-proxy in Kombinantion mit dem Let’s Encrypt Addon. Effektiv läuft das Teil passiv mit und schaut nur auf bestimmte Environment-Variablen anderer Docker Container. Sobald es diese sieht, wird automatisch ein Reverse Proxy in Nginx so konfiguriert, dass er diesen Dienst erreichbar macht und gleichzeitig wird noch ein Let’s Encrypt Cert für die entsprechende Domain besorgt und auf dem neuesten Stand gehalten.

Nun hatte ich in einem Setup mit sehr vielen gleichzeitig laufenden Diensten das Problem, dass einer der Dienste immer nur auf den ersten Request erfolgreich geantwortet hat, aber bei jedem weiteren Request nur noch einen 404 geworfen hat. Der Dienst selbst lief, Nginx hat auch keinen Fehler im Log geworfen und ich war etwas ratlos.

Nach ein paar grauen Haaren mehr und dem ein oder anderen versteckten Hinweis auf Google kam ich dann auf des Rätsels Lösung: durch ein fehlerhaftes Deployment lief kurzzeitig ein weiterer Container, der mittels der Environment Variable die gleiche URL für sich beanspruchte. Der Nginx Automatismus machte daraus automatisch einen Load Balancer. Nachdem das fehlerhafte Deployment weg war, wurde der Loadbalancer aber nicht mehr aufgelöst und somit war nur noch einer von beiden Einträgen aktiv. Warum der Nginx dann trotzdem immer wieder auf den nicht vorhandenen Host gehen wollte erschließt sich mir nicht so richtig, aber das war des Problems Lösung.

Also bin ich einfach per docker exec in den Nginx Container und habe die Datei /etc/nginx/conf.d/default editiert:


# server.name.com
upstream server.name.com {
# CONTAINER_NAME_1
server 123.45.0.67:1234;
# CONTAINER_NAME_2
server 123.45.0.78:1234;
}

Nachdem ich den Part von CONTAINER_NAME_2 gelöscht hatte, konnte ich mittels

nginx -s reload

die Config von Nginx on the fly neu laden und ab dem Moment lief der Service wieder wie gewohnt.

Nextcloud mit nginx reverse proxy macht endlos reloads

Langer Titel, einfaches Problem.

Ich habe eine Nextcloud Instanz, die lokal läuft und dann mittels Nginx Reverse Proxy aus dem Internet nur per HTTPS erreichbar ist. Nach einem der üblichen Updates endete dieses Setup, welches bis dahin problemlos lief, immer in einer Endlossschleife – aber nur für die Website. Die Nextcloud Sync Clients liefen problemlos weiter.

Mir war also klar, dass es irgendwie mit dem Reverse Proxy zusammenhängen muss. Und so war es dann auch. Nachdem ich folgendes zur Config Datei hinzugefügt hatte, lief es wieder:

'overwritehost'     => 'WWW.MEINE.DOMAIN',
'overwriteprotocol' => 'https',

Das Problem war einfach, dass scheinbar Nextcloud intern auf HTTP gehen wollte, was durch den Auto-Redirect des Nginx auf HTTPS dann für die Endlosschleife gesorgt hatte 🙂

[Quicktip] Nginx Reverse Proxy mit Basic Auth

Nehmen wir an, ihr richtet einen Nginx als reverse Proxy ein und möchtet nun, dass bestimmte Subdomains, die von anderen Servern durchgeschliffen werden, per Basic Auth “geschützt” werden sollen. Dann werdet ihr wahrscheinlich auf das Problem stoßen, dass ihr immer wieder nach dem Basic Auth Login gefragt werdet und der Reverse Proxy nicht korrekt agiert. Die Lösung ist ganz einfach: ihr müsst verhindern, dass die Basic Auth Header weitergereicht werden. Und das geht so:

server {
    listen 80;
    server_name foo.bar.com;
    access_log            /var/log/nginx/foo.access.log;
    location / {
      proxy_set_header        Authorization "";    # <== das ist die wichtige Zeile, die verhindert, dass Basic Auth weiter gereicht wird!
      auth_basic              "Protected";
      auth_basic_user_file    /etc/nginx/basic_auth;
      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;
      proxy_set_header        Host [YOUR_REMOTE_DOMAIN];
      proxy_set_header        Accept-Encoding "";
      proxy_pass              [YOUR_REMOTE_URL];
      proxy_read_timeout      90;
    }
}