Nginx - arquivo estático que serve para confusão com raiz e alias

473

Preciso veicular meu aplicativo através do servidor de aplicativos em 8080e meus arquivos estáticos de um diretório sem tocar no servidor de aplicativos. A configuração nginx que eu tenho é algo como isto ...

    # app server on port 8080
    # nginx listens on port 8123
    server {
            listen          8123;
            access_log      off;

            location /static/ {
                    # root /var/www/app/static/;
                    alias /var/www/app/static/;
                    autoindex off;
            }


            location / {
                    proxy_pass              http://127.0.0.1:8080;
                    proxy_set_header        Host             $host;
                    proxy_set_header        X-Real-IP        $remote_addr;
                    proxy_set_header        X-Forwarded-For  $proxy_add_x_forwarded_for;
            }
    }

Agora, com esta configuração, tudo está funcionando bem. Observe que a rootdiretiva está comentada.

Se eu ativar roote desativar o alias- ele pára de funcionar. No entanto, quando eu remover o arrasto /static/do rootque começa a trabalhar novamente.

Alguém pode explicar o que está acontecendo. Explique também de forma clara e verbal quais são as diferenças entre roote aliase seus propósitos.

codificador de árvore
fonte

Respostas:

1074

Encontrei respostas para minhas confusões.

Há uma diferença muito importante entre rootas aliasdiretivas e. Essa diferença existe na maneira como o caminho especificado no rootou aliasé processado.

No caso da rootdiretiva, o caminho completo é anexado à raiz, incluindo a parte do local , enquanto que no caso da aliasdiretiva, apenas a parte do caminho que NÃO inclui a parte do local é anexada ao alias .

Ilustrar:

Digamos que temos a configuração

location /static/ {
    root /var/www/app/static/;
    autoindex off;
}

Nesse caso, o caminho final que o Nginx obterá será

/var/www/app/static/static

Isso vai retorno 404já que não há static/dentrostatic/

Isso ocorre porque a parte do local é anexada ao caminho especificado em root. Portanto, com root, a maneira correta é

location /static/ {
    root /var/www/app/;
    autoindex off;
}

Por outro lado, com alias, a parte do local é descartada . Então, para a configuração

location /static/ {
    alias /var/www/app/static/;
    autoindex off;           ↑
}                            |
                             pay attention to this trailing slash

o caminho final será formado corretamente como

/var/www/app/static

O caso da barra final para aliasdiretiva

Não há orientação definitiva sobre se uma barra final é obrigatória pela documentação do Nginx , mas uma observação comum por pessoas daqui e de outros lugares parece indicar que é.

Mais alguns lugares discutiram isso, embora não conclusivamente.

/server/376162/how-can-i-create-a-location-in-nginx-that-works-with-and-without-a-trailing-slas

/server/375602/why-is-my-nginx-alias-not-working

codificador de árvore
fonte
97
A barra final no caminho alternativo é essencial!
Mafrosis
2
Tudo isso é ótimo (me ajudou a corrigir meus problemas de configuração), mas gostaria de saber quais configurações de log as pessoas poderiam usar para ajudar a diagnosticar esses tipos de problemas? Como, qualquer coisa que imprimiria em registros como "solicitação recebida, [...] correspondida por bloco de configuração" local [...] ", pesquisando diretório [...]"
Pistos
2
@Pistos: colocar log_format scripts '$document_root | $uri | > $request';em httpseção e access_log /var/log/nginx/scripts.log scripts;na serverseção do nginx configuração ..
helvete
Obrigado! Na verdade, a barra final é essencial no alias, caso contrário nginx: [emerg] invalid number of arguments in "alias" directive, recebi , e o servidor caiu durante o reinício.
FotisK
@mafrosis Por que é essencial?
Bruce Sun
104

como dizem que @treecoder

No caso da rootdiretiva, o caminho completo é anexado à raiz, incluindo a parte do local, enquanto que no caso da aliasdiretiva, apenas a parte do caminho que NÃO inclui a parte do local é anexada ao alias.

Uma imagem vale mais que mil palavras

para root:

insira a descrição da imagem aqui

para alias:

insira a descrição da imagem aqui

liuzhijun
fonte
11
A primeira seta na segunda imagem deve ser um "+"?
aioobe
35

No seu caso, você pode usar a rootdiretiva, porque $uriparte da locationdiretiva é a mesma da última rootparte da diretiva.

A documentação do Nginx também o aconselha:
Quando o local corresponde à última parte do valor da diretiva:

location /images/ {
    alias /data/w3/images/;
}

é melhor usar a diretiva root:

location /images/ {
    root /data/w3;
}

e rootdiretiva serão anexados $uriao caminho.

antonbormotov
fonte
2
Por que é melhor? Os documentos também não dizem.
HostedMetrics.com
A vantagem que eu vejo é que evitará a duplicação dos US $ uri, / imagens em determinado exemplo, ao usar apelido
antonbormotov
21

Apenas um adendo rápido à resposta muito útil do @ good_computer, eu queria substituir a raiz do URL por uma pasta, mas apenas se correspondesse a uma subpasta contendo arquivos estáticos (que eu queria manter como parte do caminho).

Por exemplo, se o arquivo solicitado estiver em /app/jsou /app/css, procure /app/location/public/[that folder].

Eu fiz isso funcionar usando um regex.

 location ~ ^/app/((images/|stylesheets/|javascripts/).*)$ {
     alias /home/user/sites/app/public/$1;
     access_log off;
     expires max;
 }
meloncholy
fonte
2
Obrigado por esta resposta. Eu sei que isso é três anos depois, mas alguém poderia explicar se há uma troca de desempenho e / ou segurança entre o uso de alias versus root?
Mina
1
@Mina É melhor usar root, se puder. (Há um comentário nos documentos wiki.nginx.org/HttpCoreModule#alias )
Matthew
Este é exatamente o que eu vim aqui para 👍👏
alienfromouterspace
6

aliasé usado para substituir o local da peça (LPP) no caminho da solicitação, enquanto o rooté usado para ser anexado ao caminho da solicitação.

São duas maneiras de mapear o caminho da solicitação para o caminho final do arquivo.

aliassó poderia ser usado no bloco de localização e substituirá a parte externa root.

aliase rootnão pode ser usado no bloco de localização juntos.

Yao Zhao
fonte
3
server {
    server_name xyz.com;
    root /home/ubuntu/project_folder/;

    client_max_body_size 10M;
    access_log  /var/log/nginx/project.access.log;
    error_log  /var/log/nginx/project.error.log;

    location /static {
        index index.html;
    }

    location /media {
        alias /home/ubuntu/project/media/;
    }
}

Bloco de servidor para viver a página estática no nginx.

Tapish
fonte
2

Em outras palavras, para manter este resumo: no caso de root, o argumento de localização especificado faz parte do caminho e do URI do sistema de arquivos . Por outro lado - o aliasargumento diretivo da declaração de localização faz parte apenas da URI

Portanto, aliasé um nome diferente que mapeia determinado URI para determinado caminho no sistema de arquivos, enquanto rootanexa o argumento de localização ao caminho raiz fornecido como argumento para a rootdiretiva.

Twissell
fonte