Как написать СУХОЙ, модульный конф nginx (обратный прокси) с именованными местоположениями


25

Я использую nginx главным образом как обратный кеширующий прокси перед несколькими приложениями gunicon / mod_wsgi и, конечно, для хранения статических файлов на сервере.

Я нахожу, что мои конфы nginx быстро становятся невозможными; проблема в том, что у меня есть несколько шаблонов, которые похожи (или даже идентичны), но мне не удается сделать его чистым.

Одна из самых больших проблем, с которыми я сталкиваюсь, заключается в том, что я хотел бы использовать именованные местоположения в качестве способа группировки набора конфессий, например.

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. Проблема не в том, что есть gunicorn и wsgi. Это всего лишь пример. Еще один:

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
}

но позвонить по названному местоположению я нашел только так:

location /somelocation {
    try_files $uri @named_location;
}

Это уже не правильно, я не хочу nginx искать статические файлы, я хочу, чтобы он шел прямо в указанное место! Есть ли способ «позвонить» названному месту напрямую ?!

Еще один способ, которым я думал, что могу пойти на сухой, это много include...

location /somelocation {
    include django_unicorn.conf;
}

Но это хороший способ сделать это? Это звучит нормально для очень общих настроек (например, прокси), но не очень читаемо, чтобы открывать разные файлы, чтобы получить полный конф.

Кроме того, в некоторых случаях я могу сгруппировать несколько мест с помощью регулярного выражения, но мне нравится делать это ТОЛЬКО, когда они логически связаны, а не только для того, чтобы иметь возможность поместить общие настройки в один и тот же блок.

Вопрос

Есть ли "официальная" лучшая практика для написания хороших, DRY-конфигураций nginx?

Я хотел бы найти образец как:

location / {
    common confs
    try_files $uri @name_location
}

** но как мне написать конкретные случаи для разных мест? **

Могу ли я просто добавить несколько мест с необычной частью conf и общей в @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
}

Если у меня разные URL-адреса, указывающие на один и тот же ресурс, я могу просто переписать?

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
}

или все они должны быть сгруппированы в одном месте?

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
}

Связанный

Я не мог найти много в списке рассылки, тем более в вики.

Обратите внимание, что это / не / так же, как вопрос NGinx Best Practices - это очень общий вопрос.

Этот другой более актуален: как мне высушить эту конфигурацию Nginx?

Ответы:


6

Я решил аналогичную проблему с помощью функции карты nginx.

Сначала создайте доменное имя для бэкэнд-карты:

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

тогда используйте карту в местоположении

location / {
  common settings
  proxy_pass $backend; 
}

Вы можете использовать любую другую переменную вместо $ http_host. См. Это руководство: http://nginx.org/en/docs/http/ngx_http_map_module.html.


Я не знал об этом map- или, по крайней мере, я никогда не замечал и думал, что смогу использовать его таким образом ... позвольте мне немного подумать об этом и посмотреть, есть ли у меня дополнительные вопросы / комментарии!
Стефано

2

Есть ли способ «позвонить» названному месту напрямую ?!

Есть еще один способ как минимум:

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

Обнаружил, что этот хак заставляет nginx забыть, например, "proxy_read_timeout", установленный внутри "/ somelocation", когда nginx "вернет" -s в "@named_location".
Денис Рыжков

1
418 Я чайник, правда?
Уолф

0

Некоторые директивы могут применяться как для контекстов «сервер», так и для «местоположения», что делает его СУХИМЫМ:

# 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;
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.