Як написати DRY, модульний nginx conf (зворотний проксі) з названими місцями


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. Проблема полягає не в тому, щоб мати як guicorn, так і 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;
}

Але це хороший спосіб зробити це? Це звучить нормально для дуже загальних налаштувань (наприклад, проксі), але не дуже читабельно потрібно відкривати різні файли, щоб отримати повну конфіденційність.

Крім того, в деяких випадках я можу згрупувати кілька локацій за допомогою регулярного виразу, але мені подобається робити це ТІЛЬКИ, коли вони логічно пов'язані не просто, щоб мати змогу розміщувати загальні налаштування в одному блоці.

Питання

Чи існує "офіційна" найкраща практика для написання гарних, сухих конфігурацій nginx?

Я хотів би знайти такий зразок:

location / {
    common confs
    try_files $uri @name_location
}

** але як мені писати конкретні випадки для різних місць? **

Чи можу я просто додати декілька локацій із нечастою частиною конфіденційності та загальною частиною в @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.

Спочатку створіть доменне ім’я на резервній карті:

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 "return" -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.