Frage Wie schreibe ich ein DRY, modular nginx conf (reverse proxy) mit benannten Orten


Ich benutze nginx hauptsächlich als reverse cachining Proxy vor mehreren gunicon / mod_wsgi Anwendungen und natürlich auf statische Serverdateien.

Ich finde, dass mein nginx confs schnell unmöglich wird, aufrechtzuerhalten; Das Problem ist, dass ich ein paar Muster habe, die ähnlich (oder sogar identisch) sind, aber ich kann es nicht schaffen, es sauber zu machen.

Eines der größten Probleme, die ich habe, ist, dass ich gerne benannte Orte als eine Möglichkeit verwenden würde, eine Menge von Konferenzen zu gruppieren, z.

location @django_modwsgi {
    include proxy.conf;
    proxy_pass  http://127.0.0.1:8080;        
}

location @django_gunicorn {
    include proxy.conf; # this could also be included directly in the server {} block?
    proxy_pass  http://gunicorn_builder;
}

NB. Das Problem ist nicht mit gunicorn und wsgi. Das ist nur ein Beispiel. Ein anderes ist:

location @namedlocation_1 {
     some cache settings;
     some cache_key settings;
     ignore some headers;
     expires;
     proxy_pass
}

location @namedlocation_2 {
     other cache settings;
     other cache_key settings;
     ignore some headers;
     expires;
     proxy_pass
}

aber um einen benannten Ort zu nennen, ist der einzige Weg, den ich gefunden habe:

location /somelocation {
    try_files $uri @named_location;
}

Das fühlt sich schon nicht richtig an, tue ich nicht will nginx nach statischen dateien suchen, ich will es direkt zum angegebenen ort bringen! Gibt es eine Möglichkeit, einen benannten Ort direkt anzurufen ?!

Eine andere Art, wie ich dachte, ich könnte trocken gehen, ist eine Menge include...

location /somelocation {
    include django_unicorn.conf;
}

Aber ist das ein guter Weg? Es klingt ok für sehr generische Einstellungen (zB proxy), aber es ist nicht gut lesbar, verschiedene Dateien öffnen zu müssen, um den kompletten conf zu erhalten.

In einigen Fällen kann ich auch einige Orte mit einem regulären Ausdruck gruppieren, aber ich mag es NUR, wenn sie logisch miteinander verwandt sind, nicht nur, um gemeinsame Einstellungen im selben Block zu speichern.

Die Frage

Gibt es eine "offizielle" Best Practice, um gute, DRY nginx-Konfigurationen zu schreiben? 

Ich würde gerne ein Muster finden wie:

location / {
    common confs
    try_files $uri @name_location
}

** aber wie schreibe ich spezifische Fälle für verschiedene Standorte? **

Könnte ich einfach mehrere Orte mit dem ungewöhnlichen Teil des conf und dem gemeinsamen Teil im @named_location hinzufügen?

location /1/ {
    some cache expire settings;
    NOTHING ELSE;
}

location /2/ {
    some other cache expire settings;
    NOTHING ELSE;
}

location / {
    common settings
    try_files
}

location @named_location {
    other common settings for this named location only
    proxy_pass
}

Wenn ich eine andere URL habe, die auf dieselbe Ressource verweist, kann ich einfach eine Neuschreibung vornehmen?

location /1/ {
    rewrite  ^  /3/  last;
}

location /2/ {
    rewrite ^   /4/  last; 
}

location / {
    common settings
    try_files
}

location @named_location {
    other common settings for this named location only
    proxy_pass
}

oder sollten diese alle an einem Ort gruppiert sein?

location / {
    rewrite ^/1/$  /3/  last;
    rewrite ^/2/$   /4/  last; 

    common settings
    try_files
}

location @named_location {
    other common settings for this named location only
    proxy_pass
}

verbunden

Ich konnte nicht viel in der Mailingliste finden, noch weniger im Wiki.

Bitte beachten Sie, dies ist / nicht / die gleiche Frage NGinx Best Practices - Das ist eine sehr allgemeine Frage.

Dieser andere ist relevanter: Wie kann ich diese Nginx-Konfiguration DRY?


24
2017-12-19 11:36


Ursprung




Antworten:


Ich habe ein ähnliches Problem mit der nginx Kartenfunktion gelöst.

Erstellen Sie zunächst einen Domänennamen für die Back-End-Karte:

map $http_host $backend {
  myhost1.tld 192.168.1.100;
  myhost2.tld 192.168.1.101;
  default     upstream_pool1;
}

Verwenden Sie dann die Karte in der Position

location / {
  common settings
  proxy_pass $backend; 
}

Sie können jede andere Variable anstelle von $ http_host verwenden Siehe dieses Handbuch: http://nginx.org/en/docs/http/ngx_http_map_module.html


4
2018-05-16 06:27



Ich wusste nichts davon map - oder zumindest habe ich es nie bemerkt und dachte, ich könnte es so gebrauchen ... lass mich ein wenig mehr darüber nachdenken und sehen, ob ich zusätzliche Fragen / Kommentare habe! - Stefano


Gibt es eine Möglichkeit, einen benannten Ort direkt anzurufen ?!

Es gibt noch einen weiteren Weg:

location /somelocation {
    error_page 418 = @named_location;
    return 418;
}

2
2018-04-02 10:26



Fand, dass dieser Hack nginx dazu bringt, z.B. "proxy_read_timeout" wird in "/ somelocation" gesetzt, wenn nginx "returns" an "@named_location" zurückgibt. - Denis Ryzhkov
418 Ich bin eine Teekanne "Ja wirklich?" - Walf


Einige Direktiven können sowohl für "Server" - als auch für "Standort" -Kontexte angewendet werden, wodurch DRY erzeugt wird:

# The variables below are evaluated on each request,
# allowing to DRY configs of locations.
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Real-IP $remote_addr;

location /special {
    proxy_send_timeout 10m;
    proxy_read_timeout 10m;
    proxy_pass http://pool;
}

location / {
    proxy_pass http://pool;
}

0
2018-04-13 12:53