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

473

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 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 funciona bien. Tenga en cuenta que la rootdirectiva está comentada.

Si activo rooty desactivo el alias- deja de funcionar. Sin embargo, cuando elimino el final /static/del root, comienza a funcionar nuevamente.

¿Alguien puede explicar lo que está pasando? También explique de manera clara y detallada cuáles son las diferencias entre rooty alias, y sus propósitos.

codificador de árboles
fuente

Respuestas:

1074

He encontrado respuestas a mis confusiones.

Hay una diferencia muy importante entre rootlas aliasdirectivas y las directivas. 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 agrega a la ruta especificada en root. Por lo tanto, con root, la forma correcta es

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

Por otro lado, con alias, la parte de ubicación se cae . 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

El caso de la barra inclinada final para la aliasdirectiva

No existe una directriz definitiva sobre si una barra diagonal 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 sí lo es.

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

/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 árboles
fuente
97
¡La barra inclinada final en el camino de alias es esencial!
mafrosis
2
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 se imprima en registros como "solicitud recibida de [...], junto con el bloque de configuración" ubicación [...] ", búsqueda de directorio [...]"
Pistos
2
@Pistos: poner log_format scripts '$document_root | $uri | > $request';en httpsección y access_log /var/log/nginx/scripts.log scripts;en serversección de nginx config ..
helvete
¡Gracias! De hecho, la barra diagonal final es esencial en el alias, de lo contrario lo obtuve nginx: [emerg] invalid number of arguments in "alias" directive, y el servidor se cayó durante su reinicio.
FotisK
@mafrosis ¿Por qué es esencial?
Bruce Sun
104

como decir como @treecoder

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.

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í

liuzhijun
fuente
11
¿Debería la primera flecha en la segunda imagen ser un "+"?
aioobe
35

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

La documentación de Nginx también lo aconseja:
cuando la ubicación coincide con la última parte del valor de la directiva:

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

es mejor usar la directiva raíz en su lugar:

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

y la rootdirectiva se agregará $urial camino.

antonbormotov
fuente
2
¿Por qué es mejor? Los doctores tampoco lo dicen.
HostedMetrics.com
El beneficio que veo es evitar la duplicación de $ uri, / imágenes en el ejemplo dado, cuando se usa alias
antonbormotov
21

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 /app/location/public/[that folder].

Tengo esto para trabajar usando una expresión regular.

 location ~ ^/app/((images/|stylesheets/|javascripts/).*)$ {
     alias /home/user/sites/app/public/$1;
     access_log off;
     expires max;
 }
meloncolía
fuente
2
Gracias por esta respuesta Sé que esto es 3 años después, pero ¿alguien podría explicar si existe una compensación de rendimiento y / o seguridad entre el uso de alias versus root?
Mina
1
@Mina Es mejor usar root si puedes. (Hay un comentario en los documentos wiki.nginx.org/HttpCoreModule#alias )
Matthew Wilcoxson
Esto es exactamente para lo que vine aquí alien
alienfromouterspace
6

alias se utiliza para reemplazar la ruta de la parte de ubicación (LPP) en la ruta de solicitud, mientras que el root se usa para anteponerse a la ruta de solicitud.

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

alias solo podría usarse en el bloque de ubicación, y anulará el exterior root .

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

Yao Zhao
fuente
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/;
    }
}

Bloqueo del servidor para vivir la página estática en nginx.

Tapish
fuente
2

En otras palabras, para mantener este resumen: en caso de root, el argumento de ubicación especificado es parte de la ruta y el URI del sistema de archivos . Por otro lado, el aliasargumento directivo de la declaración de ubicación es parte de URI

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

Twissell
fuente