Nginx: archivo estático que proporciona confusión con root y alias

570

Necesito servir mi aplicación a través de mi servidor de aplicaciones en 8080, y mis archivos estáticos desde un directorio sin tocar el servidor de aplicaciones. La configuración de nginx que tengo es algo como esto ...

    # 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;
            }
    }

Ahora, con esta configuración, todo está funcionando bien. Tenga en cuenta que la rootdirectiva está comentada.

Si activo rooty desactivo el alias- deja de funcionar. Sin embargo, cuando quito el arrastre /static/de la rootque empiece a funcionar de nuevo.

¿Alguien puede explicar qué está pasando? Además, explique de forma clara y detallada cuáles son las diferencias entre rooty alias, y sus propósitos.

0
1255

He encontrado respuestas a mis confusiones.

Hay una diferencia muy importante entre rootlas aliasdirectivas y. Esta diferencia existe en la forma en que se procesa la ruta especificada en rooto alias.

En el caso de la rootdirectiva, la ruta completa se agrega a la raíz, incluida la parte de ubicación , mientras que en el caso de la aliasdirectiva, solo la parte de la ruta que NO incluye la parte de ubicación se agrega al alias .

Para ilustrar:

Digamos que tenemos la configuración

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

En este caso, la ruta final que derivará Nginx será

/var/www/app/static/static

Esto va a volver 404ya que no hay static/dentrostatic/

Esto se debe a que la parte de ubicación se adjunta a la ruta especificada en root. Por tanto, con root, la forma correcta es

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

Por otro lado, con aliasla parte de situación se dejó caer . Entonces para la configuración

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

la ruta final se formará correctamente como

/var/www/app/static

En cierto modo, esto tiene sentido. Los aliassólo te permite definir un nuevo camino para representar un camino "real" existente. La parte de la ubicación es esa nueva ruta, por lo que se reemplaza con la ruta real. Piense en ello como un enlace simbólico.

Root, por otro lado, no es una ruta nueva, contiene cierta información que tiene que ser cotejada con alguna otra información para hacer la ruta final. Y así, la parte de ubicación se usa, no se quita.

El caso de la barra diagonal en alias

No existe una pauta definitiva sobre si una barra inclinada es obligatoria según la documentación de Nginx , pero una observación común de personas aquí y en otros lugares parece indicar que lo es.

Algunos lugares más han discutido esto, aunque no de manera concluyente.

https://serverfault.com/questions/376162/how-can-i-create-a-location-in-nginx-that-works-with-and-without-a-trailing-slas

https://serverfault.com/questions/375602/why-is-my-nginx-alias-not-working

8
  • 122
    ¡La barra diagonal en la ruta de alias es esencial! 16 de diciembre de 2015 a las 7:30
  • 5
    Todo esto es genial (me ayudó a solucionar mis problemas de configuración), pero me pregunto qué configuraciones de registro podrían usar las personas para ayudar a diagnosticar este tipo de problemas. Por ejemplo, cualquier cosa que imprima en registros cosas como "solicitud recibida de [...], emparejada con el bloque de configuración de" ubicación [...] ", directorio de búsqueda [...]"
    Pistos
    5 de junio de 2018 a las 17:18
  • 3
    @Pistos: poner log_format scripts '$document_root | $uri | > $request';en la httpsección y access_log /var/log/nginx/scripts.log scripts;en la serversección de la configuración de nginx.
    helvete
    6/06/18 a las 13:24
  • ¡Gracias! De hecho, la barra diagonal es esencial en el alias; de lo contrario nginx: [emerg] invalid number of arguments in "alias" directive, obtuve y el servidor se cayó durante su reinicio.
    FotisK
    18/07/18 a las 21:36
  • @mafrosis ¿Por qué es imprescindible? 25 feb.20 a las 2:17
130

como dice @treecoder

In case of the root directive, full path is appended to the root including the location part, whereas in case of the alias directive, only the portion of the path NOT including the location part is appended to the alias.

Una imagen vale mas que mil palabras

para root:

ingrese la descripción de la imagen aquí

para alias:

ingrese la descripción de la imagen aquí

1
  • 22
    ¿La primera flecha de la segunda imagen debería ser un "+"?
    aioobe
    21/10/2017 a las 9:32
41

En su caso, puede usar la rootdirectiva, porque $uriparte de la locationdirectiva es la misma que la última rootparte de la directiva.

Nginx documentation advices it as well:
When location matches the last part of the directive’s value:

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

it is better to use the root directive instead:

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

y la rootdirectiva se agregará $uria la ruta.

2
  • 3
    ¿Por qué es mejor? Los doctores tampoco lo dicen. 26 de diciembre de 2017 a las 17:35
  • El beneficio que veo es evitar la duplicación de $ uri, / imágenes en el ejemplo dado, al usar alias 26 de diciembre de 2017 a las 17:42
22

Solo un apéndice rápido a la muy útil respuesta de @ good_computer, quería reemplazar la raíz de la URL con una carpeta, pero solo si coincidía con una subcarpeta que contenía archivos estáticos (que quería conservar como parte de la ruta).

Por ejemplo, si el archivo solicitado está en /app/jso /app/css, busque en /app/location/public/[that folder].

Conseguí que esto funcionara usando una expresión regular.

 location ~ ^/app/((images/|stylesheets/|javascripts/).*)$ {
     alias /home/user/sites/app/public/$1;
     access_log off;
     expires max;
 }
4
8

aliasse usa para reemplazar la ruta de la parte de la ubicación (LPP) en la ruta de la solicitud, mientras que rootse usa para anteponer la ruta de la solicitud.

Son dos formas de asignar la ruta de la solicitud a la ruta del archivo final.

aliassolo se puede usar en el bloque de ubicación y anulará el exterior root.

aliasy rootno se pueden usar juntos en un bloque de ubicación.

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/;
    }
}

Bloque de servidor para vivir la página estática en nginx.

1
2

En otras palabras, sea breve: en el caso de que el rootargumento de ubicación especificado sea parte de la ruta del sistema de archivos y el URI . Por otro lado, para el aliasargumento de directiva de la declaración de ubicación es solo parte de URI

Entonces, aliases un nombre diferente que asigna cierta URI a cierta ruta en el sistema de archivos, mientras que rootagrega un argumento de ubicación a la ruta raíz dada como argumento a la rootdirectiva.

2

Aunque mi respuesta no es necesaria, pero creo que es necesario agregar esto, rooty aliasfunciona de manera diferente cuando se trata de expresiones regulares.

 location ~ /static/my.png$ {
 alias /var/www/static/;
 access_log off;
 expires max;}

En este caso, la coincidencia de expresiones regulares no se agregará con alias, nginx buscará solo '/ var / www / static /' no '/var/www/static/my.png'. Tienes que usar la captura de expresiones regulares.

 location ~ /static/my.png$ {
 root /var/www;
 access_log off;
 expires max;}

En este caso, la URL coincidente que se agregará con la raíz, nginx buscará '/var/www/static/my.png'.