Nginx -- static file serving confusion with root & alias

nginx

Solution

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.

`root`

- the `location` part is appended to `root` part

- final path = `root` + `location`

`alias`

- the `location` part is replaced by the `alias` part

- final path = `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

In a way this makes sense. The `alias` just lets you define a new path to represent an existing "real" path. The location part is that new path, and so it gets replaced with the real path. Think of it as a symlink.

Root, on the other hand is not a new path, it contains some information that has to be collated with some other info to make the final path. And so, the location part is used, not dropped.

The case for trailing slash in `alias`

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

Problem

I need to serve my app through my app server at `8080`, and my static files from a directory without touching the app server. ``` # 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 `root`, it starts working again. Can someone explain what's going on?

Original source