Static files: root, alias and try_files

NGINX · Essentials · 10 min

Serving front-end builds and assets from NGINX is fast and common, and root vs alias mistakes cause most 404s.

root sets the directory that the full URI is appended to: with root /var/www/site;, a request for /img/logo.png reads /var/www/site/img/logo.png.

alias replaces the matched location prefix instead: in location /static/ { alias /srv/assets/; }, /static/app.js reads /srv/assets/app.js. Keep the trailing slashes consistent on both, or paths get glued together wrongly.

index index.html; names the file served for a request ending in /.

try_files checks alternatives in order and uses the first that exists; the last parameter is a fallback URI (or =404):

  • try_files $uri $uri/ =404;: the file, then a directory with an index, otherwise 404.
  • try_files $uri /index.html;: the classic single-page application setup: unknown paths serve index.html so the client-side router can handle them.

Other useful directives for static content:

  • expires 30d; or add_header Cache-Control ... for browser caching of fingerprinted assets.
  • autoindex on; for a directory listing (rarely wanted in production).
  • MIME types come from mime.types; a wrong Content-Type usually means it isn't included.

NGINX uses the sendfile system call to send files without copying them through user space, which makes static serving very cheap.

Example

server {
    listen 80;
    server_name app.example.com;
    root /var/www/app/dist;             # /about -> /var/www/app/dist/about
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;   # SPA fallback
    }

    location /assets/ {
        expires 1y;                     # fingerprinted, safe to cache long
        access_log off;
    }

    location /downloads/ {
        alias /srv/files/;              # /downloads/a.zip -> /srv/files/a.zip
    }
}

Remember

  • root appends the full URI; alias replaces the location prefix
  • try_files tries files in order, then falls back
  • try_files $uri /index.html serves single-page apps

Watch out for

  • Using root where alias was meant: /downloads/a.zip becomes /srv/files/downloads/a.zip.

Check yourself

  1. With location /img/ { root /data; }, which file serves /img/a.png?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: nginx.org/en/docs/http/ngx_http_core_module.html#try_files