Nginx — static file serving confusion with root &

2019-01-02 16:08发布

I need to serve my app through my app server at 8080, and my static files from a directory without touching the app server. The nginx config I have is something like this...

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

Now, with this config, everything is working fine. Note that the root directive is commented out.

If I activate root and deactivate the alias -- it stops working. However, when I remove the trailing /static/ from the root it starts working again.

Can someone explain what's going on. Also please explain clearly and verbosely what are the differences between root and alias, and their purposes.

标签: nginx
5条回答
深知你不懂我心
2楼-- · 2019-01-02 16:44

Just a quick addendum to @good_computer's very helpful answer, I wanted to replace to root of the URL with a folder, but only if it matched a subfolder containing static files (which I wanted to retain as part of the path).

For example if file requested is in /app/js or /app/css, look in /app/location/public/[that folder].

I got this to work using a regex.

 location ~ ^/app/((images/|stylesheets/|javascripts/).*)$ {
     alias /home/user/sites/app/public/$1;
     access_log off;
     expires max;
 }
查看更多
流年柔荑漫光年
3楼-- · 2019-01-02 16:45

as say as @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.

A picture is worth a thousand words

for root:

enter image description here

for alias:

enter image description here

查看更多
不再属于我。
4楼-- · 2019-01-02 16:47

I have found answers to my confusions.

There is a very important difference between the root and the alias directives. This difference exists in the way the path specified in the root or the alias is processed.

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.

To illustrate:

Let's say we have the config

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

In this case the final path that Nginx will derive will be

/var/www/app/static/static

This is going to return 404 since there is no static/ within static/

This is because the location part is appended to the path specified in the root. Hence, with root, the correct way is

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

On the other hand, with alias, the location part gets dropped. So for the config

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

the final path will correctly be formed as

/var/www/app/static

See the documentation here: http://wiki.nginx.org/HttpCoreModule#alias

查看更多
弹指情弦暗扣
5楼-- · 2019-01-02 16:52
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/;
    }
}

Server block to live the static page on nginx.

查看更多
牵手、夕阳
6楼-- · 2019-01-02 16:59

In your case, you can use root directive, because $uri part of the location directive is the same with last root directive part.

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

and root directive will append $uri to the path.

查看更多
登录 后发表回答