Jak napisać SUCHY, modułowy conf nginx (odwrotne proxy) z nazwanymi lokalizacjami

25

Używam nginx głównie jako odwrotnego buforowania proxy przed kilkoma aplikacjami gunicon / mod_wsgi i oczywiście do plików statycznych serwera.

Przekonałem się, że szybko moje nginx confs stają się niemożliwe do utrzymania; Problem polega na tym, że mam kilka wzorów, które są podobne (lub nawet identyczne), ale nie mogę tego zrobić.

Jednym z największych problemów, jakie mam, jest to, że chciałbym używać nazwanych lokalizacji jako sposobu grupowania zestawu konf, np.

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. Problemem nie jest zarówno gunicorn, jak i wsgi. To tylko przykład. Kolejny to:

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
}

ale aby zadzwonić do nazwanej lokalizacji, jedynym sposobem, jaki znalazłem, jest:

location /somelocation {
    try_files $uri @named_location;
}

To już nie wydaje się właściwe, nie chcę, aby nginx szukał plików statycznych, chcę, aby przechodziło bezpośrednio do wskazanej lokalizacji! Czy istnieje sposób na bezpośrednie wywołanie nazwanej lokalizacji ?!

Innym sposobem, w jaki mogłem iść na sucho, jest dużo include...

location /somelocation {
    include django_unicorn.conf;
}

Ale czy to dobry sposób, aby to zrobić? Brzmi dobrze dla bardzo ogólnych ustawień (np. Proxy), ale nie jest zbyt czytelne, aby otwierać różne pliki, aby uzyskać pełną konf.

Ponadto, w niektórych przypadkach mogę pogrupować kilka lokalizacji za pomocą wyrażenia regularnego, ale lubię to robić TYLKO wtedy, gdy są one logicznie powiązane, nie tylko po to, aby móc umieścić wspólne ustawienia w tym samym bloku.

Pytanie

Czy istnieje „oficjalna” najlepsza praktyka pisania dobrych konfiguracji DRY nginx?

Chciałbym znaleźć wzór taki jak:

location / {
    common confs
    try_files $uri @name_location
}

** ale jak napisać konkretne przypadki dla różnych lokalizacji? **

Czy mogę po prostu dodać kilka lokalizacji z nietypową częścią conf i wspólną w @named_location?

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
}

Kiedy mam inny adres URL wskazujący na ten sam zasób, czy mogę po prostu przepisać?

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
}

czy wszystkie powinny być zgrupowane w jednym miejscu?

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
}

Związane z

Nie mogłem znaleźć wiele na liście mailingowej, tym bardziej na wiki.

Pamiętaj, że jest to / nie / to samo co pytanie NGinx Best Practices - to bardzo ogólne pytanie.

Ten drugi jest bardziej odpowiedni: Jak mogę WYSUSZIĆ tę konfigurację Nginx?

Stefano
źródło

Odpowiedzi:

6

Rozwiązałem podobny problem za pomocą funkcji mapy Nginx.

Najpierw utwórz nazwę domeny do mapy zaplecza:

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

następnie użyj mapy w lokalizacji

location / {
  common settings
  proxy_pass $backend; 
}

Możesz użyć dowolnej innej zmiennej zamiast $ http_host Zobacz ten podręcznik: http://nginx.org/en/docs/http/ngx_http_map_module.html

DukeLion
źródło
Nie wiedziałam o tym map- a przynajmniej nigdy tego nie zauważyłam i pomyślałam, że mogę to wykorzystać w ten sposób ... pozwólcie mi się zastanowić nad tym i sprawdzić, czy mam dodatkowe pytania / komentarze!
Stefano
2

Czy istnieje sposób na bezpośrednie wywołanie nazwanej lokalizacji ?!

Jest co najmniej jeszcze jeden sposób:

location /somelocation {
    error_page 418 = @named_location;
    return 418;
}
MingalevME
źródło
Stwierdzono, że ten hack powoduje, że nginx zapomina np. „Proxy_read_timeout” ustawiony wewnątrz „/ somelocation”, gdy nginx „zwraca” -s do „@named_location”.
Denis Ryżkow
1
418 Jestem czajnikiem Naprawdę?
Walf
0

Niektóre dyrektywy można zastosować zarówno w kontekście „serwera”, jak i „lokalizacji”, co powoduje, że jest SUCHY:

# 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;
}
Denis Ryżkow
źródło