Lesson 6 / 25

Serving Static Files and Single-Page Apps

Serve files efficiently with root, alias, try_files and caching headers.

Files straight from disk

NGINX serves static files very efficiently. root /var/www/site; maps a request URI to a path by appending the full URI: /images/a.png becomes /var/www/site/images/a.png. alias inside a location replaces the matched prefix: location /media/ { alias /data/uploads/; } maps /media/a.png to /data/uploads/a.png (keep trailing slashes consistent on both). index lists files to try for directory requests. try_files checks files in order and falls back to the last argument: try_files $uri $uri/ =404; for normal sites, and try_files $uri $uri/ /index.html; for single-page applications, so client-side routes such as /orders/42 load the app shell instead of a 404. Enable sendfile on; for kernel-level file transfer. Set caching headers with expires or add_header Cache-Control: long-lived and immutable for fingerprinted assets, short or no-cache for index.html. Never point root at a directory containing source code or secrets.

A single-page app with long-cached assets

The HTML is always revalidated; hashed assets are cached for a year.

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

    location /assets/ {
        expires 1y;
        add_header Cache-Control "public, max-age=31536000, immutable";
        try_files $uri =404;
    }

    location /uploads/ {
        alias /data/uploads/;              # /uploads/a.png -> /data/uploads/a.png
    }

    location / {
        add_header Cache-Control "no-cache";
        try_files $uri $uri/ /index.html;  # client-side routes load the app
    }
}

root inside location is usually a smell

Set root once at server level and let locations inherit it. Repeating root in many locations is error-prone; use alias only when a location must map to a different directory.

Quick check: With `location /media/ { alias /data/uploads/; }`, which file serves /media/cat.png?

  • /data/uploads/cat.png
  • /data/uploads/media/cat.png
  • /media/cat.png
  • /var/www/media/cat.png
Answer

/data/uploads/cat.png — alias replaces the matched prefix, whereas root would append the whole URI.