Como escrever um nginx conf (proxy reverso) modular com locais nomeados

25

Estou usando o nginx principalmente como um proxy de cache reverso na frente de vários aplicativos gunicon / mod_wsgi e, é claro, para servidores de arquivos estáticos.

Acho que rapidamente meus confs de nginx se tornam impossíveis de manter; A questão é que eu tenho alguns padrões que são semelhantes (ou mesmo idênticos), mas não consigo fazer isso limpo.

Um dos maiores problemas que tenho é que eu adoraria usar locais nomeados como forma de agrupar um conjunto de confs, por exemplo.

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. A questão é não ter ambos gunicorn e wsgi. Isso é apenas um exemplo. Outra é:

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
}

mas para chamar um local nomeado, a única maneira que encontrei é:

location /somelocation {
    try_files $uri @named_location;
}

Isso já não parece certo, eu não quero que o nginx vá procurar arquivos estáticos, eu quero que ele vá diretamente para o local nomeado! Existe uma maneira de "chamar" um local nomeado diretamente?!

Outra maneira que eu pensei que eu poderia ir para secar é um monte de include ...

location /somelocation {
    include django_unicorn.conf;
}

Mas isso é uma boa maneira de fazer isso? Parece bom para configurações muito genéricas (por exemplo, proxy), mas não é muito legível para ter que abrir arquivos diferentes para obter o conf completo.

Além disso, em alguns casos, posso agrupar alguns locais com um regexp, mas gosto de fazer isso APENAS quando eles estão logicamente relacionados, não apenas para poder colocar configurações comuns no mesmo bloco.

A questão

Existe uma boa prática "oficial" para escrever boas configurações nginx DRY?

Eu adoraria encontrar um padrão como:

location / {
    common confs
    try_files $uri @name_location
}

** mas como escrevo casos específicos para locais diferentes? **

Posso simplesmente adicionar vários locais com a parte incomum do conf e o comum no @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
}

Quando eu tenho um URL diferente apontando para o mesmo recurso, posso simplesmente reescrever?

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
}

ou devem ser todos agrupados em um único local?

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
}

Relacionado

Eu não encontrei muito na lista de discussão, ainda menos na wiki.

Por favor, note que isto é / não / é o mesmo que pergunta Práticas recomendadas da NGinx - isso é muito genérico pergunta.

Este outro é mais relevante: Como faço para DRY up this Configuração Nginx?

    
por Stefano 19.12.2011 / 12:36

3 respostas

4

Eu resolvi um problema semelhante usando o recurso de mapa nginx.

Primeiro, crie um nome de domínio para o mapa de back-end:

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

use o mapa na localização

location / {
  common settings
  proxy_pass $backend; 
}

Você pode usar qualquer outra variável em vez de $ http_host Veja este manual: link

    
por 16.05.2012 / 08:27
2

Is there a way to "call" a named location directly?!

Há mais uma maneira, pelo menos:

location /somelocation {
    error_page 418 = @named_location;
    return 418;
}
    
por 02.04.2014 / 12:26
0

Algumas diretivas podem ser aplicadas para os contextos "servidor" e "local", tornando-se DRY:

# 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;
}
    
por 13.04.2015 / 14:53