Nginx -- static file serving confusion with root & alias

treecoder picture treecoder · May 17, 2012 · Viewed 270.9k times · Source

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.

Answer

treecoder picture treecoder · May 18, 2012

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;           ↑
}                            |
                             pay attention to this trailing slash

the final path will correctly be formed as

/var/www/app/static

The case of trailing slash for alias directive

There is no definitive guideline about whether a trailing slash is mandatory per Nginx documentation, but a common observation by people here and elsewhere seems to indicate that it is.

A few more places have discussed this, not conclusively though.

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