Nginx —静态文件,混淆了根和别名


473

我需要通过我的应用服务器(位于)为我的应用提供服务8080,并从目录中获取我的静态文件,而无需触摸应用服务器。我拥有的Nginx配置是这样的...

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

现在,使用此配置,一切正常。请注意,该root指令已被注释掉。

如果我启用root和停用alias--它将停止工作。但是,当我/static/从中删除尾迹时,root它将再次开始工作。

有人可以解释发生了什么。还请解释清楚和冗长之间有什么区别rootalias和它们的用途。

Answers:


1074

我找到了解决我困惑的答案。

rootalias指令之间有一个非常重要的区别。这种差异存在于处理root或中指定的路径的方式上alias

在使用root伪指令的情况下,完整路径将附加到包含位置部分的根目录,而在使用alias伪指令的情况下,仅路径的不包括位置部分的部分才附加到别名

为了显示:

假设我们有配置

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

在这种情况下,Nginx将得出的最终路径将是

/var/www/app/static/static

这是要回报404,因为没有static/static/

这是因为位置部分已附加到中指定的路径中root。因此,使用root,正确的方法是

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

另一方面,有了alias,位置部分就掉了。所以对于配置

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

最终路径将正确地形成为

/var/www/app/static

alias指令后跟斜杠的情况

Nginx文档中没有关于是否必须使用斜杠的明确指南,但国内外其他人的普遍观察似乎表明确实如此。

尽管还没有最终结论,但还有更多地方对此进行了讨论。

/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


97
别名路径上的斜杠必不可少!
羊膜病

2
一切都很好(它帮助我解决了配置问题),但我想知道人们可以使用哪些日志记录设置来帮助诊断此类问题?就像会打印到日志内容的任何内容,例如“收到的[...]请求,与“ location [...]”配置块匹配,搜索目录[]”
Pistos

2
@Pistos:把log_format scripts '$document_root | $uri | > $request';http段和access_log /var/log/nginx/scripts.log scripts;servernginx的配置..第
helvete

谢谢!的确,别名上的尾部斜杠是必不可少的,否则,我会收到nginx: [emerg] invalid number of arguments in "alias" directive,并且服务器在重新启动期间发生故障。
FotisK

@mafrosis为什么必不可少?
布鲁斯

104

如@treecoder

在使用root伪指令的情况下,完整路径将附加到包含位置部分的根,而在使用alias伪指令的情况下,仅路径的不包括位置部分的部分将附加到别名。

一张图片胜过千言万语

root

在此处输入图片说明

alias

在此处输入图片说明


11
第二个图像中的第一个箭头应该是“ +”吗?
aioobe

35

你的情况,你可以使用root指令,因为$uri该部分location指令是与去年相同的root指令部分。

Nginx文档也建议:
当位置与指令值的最后一部分匹配时:

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

最好改用root指令:

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

root指令将追加$uri到路径。


2
为什么会更好?文件也不说。
HostedMetrics.com

我看到的好处是,使用别名时,在给定的示例中,避免重复$ uri,/ images
antonbormotov

21

只是@good_computer非常有用的答案的快速附录,我想用一个文件夹替换URL的根目录,但前提是它与包含静态文件的子文件夹匹配(我希望将其保留为路径的一部分)。

例如,如果请求的文件位于/app/js或中/app/css,请查找/app/location/public/[that folder]

我让它使用正则表达式工作。

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

2
感谢您的回答。我知道这是3年后的事,但是谁能解释使用别名和root之间是否存在性能和/或安全性的折衷?
米娜

1
@Mina如果可以的话,最好使用root。(文档wiki.nginx.org/HttpCoreModule#alias中有评论)
Matthew Wilcoxson,

这正是我来这里👍👏的目的
Alienfromouterspace

6

alias用来代替请求路径中的位置部分路径(LPP),而root用来放在请求路径之前。

它们是将请求路径映射到最终文件路径的两种方法。

alias只能在位置块中使用,它将覆盖outside root

alias并且root不能一起在位置块中使用。


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

服务器阻止在nginx上驻留静态页面。


2

换句话说,保持简短:如果是root,指定的location参数是文件系统的path和URI的一部分。另一方面-对于aliaslocation语句的指令参数,URI的一部分

因此,alias是一个将特定URI映射到文件系统中特定路径的不同名称,而root将location参数附加到作为root指令的参数给出的根路径。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.