Nginx - fichier statique au service de la confusion avec la racine et l'alias

473

Je dois servir mon application via mon serveur d'applications sur 8080et mes fichiers statiques à partir d'un répertoire sans toucher au serveur d'applications. La configuration nginx que j'ai est quelque chose comme ça ...

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

Maintenant, avec cette configuration, tout fonctionne bien. Notez que la rootdirective est commentée.

Si j'active rootet désactive le alias- il cesse de fonctionner. Cependant, lorsque je supprime la fin /static/de la, rootelle recommence à fonctionner.

Quelqu'un peut-il expliquer ce qui se passe. Veuillez également expliquer clairement et verbalement quelles sont les différences entre rootet aliaset leurs objectifs.

treecoder
la source

Réponses:

1074

J'ai trouvé des réponses à mes confusions.

Il existe une différence très importante entre rootles aliasdirectives et les directives. Cette différence existe dans la façon dont le chemin spécifié dans le rootou le aliasest traité.

Dans le cas de la rootdirective, le chemin complet est ajouté à la racine, y compris la partie emplacement , tandis que dans le cas de la aliasdirective, seule la partie du chemin N'incluant pas la partie emplacement est ajoutée à l'alias .

Pour illustrer:

Disons que nous avons la config

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

Dans ce cas, le chemin final que Nginx dérivera sera

/var/www/app/static/static

Cela va revenir 404car il n'y a pas à l' static/intérieurstatic/

En effet, la partie emplacement est ajoutée au chemin spécifié dans le root. Par conséquent, avec root, la bonne façon est

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

En revanche, avec alias, la partie emplacement est supprimée . Donc pour la config

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

le chemin final sera correctement formé comme

/var/www/app/static

Le cas de la barre oblique finale pour la aliasdirective

Il n'y a pas de directive définitive quant à savoir si une barre oblique finale est obligatoire selon la documentation Nginx , mais une observation courante par des gens d'ici et d'ailleurs semble indiquer que c'est le cas.

Quelques autres endroits en ont discuté, mais de manière non concluante.

/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

treecoder
la source
97
La barre oblique de fin sur le chemin d'alias est essentielle!
mafrosis
2
C'est très bien (cela m'a aidé à résoudre mes problèmes de configuration), mais je me demande quels paramètres de journalisation les gens pourraient utiliser pour aider à diagnostiquer ce genre de problèmes? Par exemple, tout ce qui s'imprime dans les journaux, comme "demande reçue pour [...], assortie d'un bloc de configuration" emplacement [...] ", recherche dans le répertoire [...]"
Pistos
2
@Pistos: mettre log_format scripts '$document_root | $uri | > $request';en httpsection et access_log /var/log/nginx/scripts.log scripts;en serversection de configuration nginx ..
helvete
Merci! En effet la barre oblique de fin est essentielle sur l'alias, sinon je l'ai eu nginx: [emerg] invalid number of arguments in "alias" directive, et le serveur est tombé en panne lors de son redémarrage.
FotisK
@mafrosis Pourquoi est-ce essentiel?
Bruce Sun
104

comme dire comme @treecoder

Dans le cas de la rootdirective, le chemin complet est ajouté à la racine, y compris la partie emplacement, tandis que dans le cas de la aliasdirective, seule la partie du chemin N'incluant pas la partie emplacement est ajoutée à l'alias.

Une image vaut mieux que mille mots

pour root:

entrez la description de l'image ici

pour alias:

entrez la description de l'image ici

liuzhijun
la source
11
La première flèche de la deuxième image doit-elle être un "+"?
aioobe
35

Dans votre cas, vous pouvez utiliser la rootdirective, car une $uripartie de la locationdirective est identique à la dernière rootpartie de la directive.

La documentation Nginx le conseille également:
Lorsque l'emplacement correspond à la dernière partie de la valeur de la directive:

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

il vaut mieux utiliser la directive racine à la place:

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

et la rootdirective s'ajoutera $uriau chemin.

antonbormotov
la source
2
Pourquoi est-ce mieux? Les documents ne disent pas non plus.
HostedMetrics.com
L'avantage que je vois est d'éviter la duplication de $ uri, / images dans l'exemple donné, lors de l'utilisation d'alias
antonbormotov
21

Juste un addendum rapide à la réponse très utile de @ good_computer, je voulais remplacer la racine de l'URL par un dossier, mais seulement si elle correspondait à un sous-dossier contenant des fichiers statiques (que je voulais conserver dans le cadre du chemin).

Par exemple, si le fichier demandé est dans /app/jsou /app/css, regardez dans /app/location/public/[that folder].

Je l'ai fait fonctionner avec une expression régulière.

 location ~ ^/app/((images/|stylesheets/|javascripts/).*)$ {
     alias /home/user/sites/app/public/$1;
     access_log off;
     expires max;
 }
meloncholy
la source
2
Merci pour cette réponse. Je sais que c'est 3 ans plus tard, mais quelqu'un pourrait-il expliquer s'il y a un compromis entre les performances et / ou la sécurité entre l'utilisation d'alias et root?
Mina
1
@Mina Il vaut mieux utiliser root si vous le pouvez. (Il y a un commentaire dans la documentation wiki.nginx.org/HttpCoreModule#alias )
Matthew Wilcoxson
C'est exactement pour cela que je suis venu ici al
alienfromouterspace
6

aliasest utilisé pour remplacer le chemin de partie d'emplacement (LPP) dans le chemin de demande, tandis que le rootest utilisé pour être ajouté au chemin de demande.

Il existe deux façons de mapper le chemin de la demande sur le chemin du fichier final.

aliasne peut être utilisé que dans le bloc d'emplacement, et il remplacera l'extérieur root.

aliaset rootne peut pas être utilisé dans le bloc de localisation ensemble.

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

Bloc serveur pour vivre la page statique sur nginx.

Tapish
la source
2

En d'autres termes sur la conservation de cette brève: dans le cas de root, l'argument emplacement spécifié fait partie du chemin du système de fichiers et de l'URI . D'un autre côté - car l' aliasargument de directive de l'instruction location fait partie de l' URI uniquement

Donc, aliasc'est un nom différent qui mappe certains URI à certains chemins dans le système de fichiers, tandis que rootajoute l'argument location au chemin racine donné comme argument à la rootdirective.

Twissell
la source