Site icon GetPageSpeed

NGINX Alias vs Root: End the Confusion Once and For All

NGINX Alias vs Root: End the Confusion Once and For All

The confusion between NGINX alias and root directives has caused more broken configurations than almost any other NGINX concept. If you have ever spent hours debugging why your static files return 404 errors, or wondered why your perfectly valid-looking configuration does not work, you are not alone.

In this guide, you will learn exactly how NGINX alias vs root differs at the implementation level. We will examine how NGINX constructs file paths internally, when to use each directive, and the critical trailing slash rules that trip up even experienced administrators. Every configuration in this article has been tested on Rocky Linux 10 with NGINX 1.26.

How NGINX Constructs File Paths

Before we can understand the difference between alias and root, we need to understand how NGINX maps a URL to a file on disk. This path construction happens in the ngx_http_map_uri_to_path() function deep in NGINX’s core module.

When a request comes in, NGINX must translate the requested URI into an actual filesystem path. According to the official NGINX documentation, the path construction formula differs between root and alias:

With root:

filesystem_path = root + full_URI

With alias:

filesystem_path = alias + (URI - location_match)

This fundamental difference is the source of all the confusion around NGINX alias vs root. Let us see it in action.

The root Directive: Appending the Full URI

The root directive specifies a base directory, and NGINX appends the entire request URI to it. This is the simpler of the two directives and should be your default choice when choosing between NGINX alias vs root.

server {
    listen 80;
    server_name example.com;

    location /images {
        root /var/www/html;
    }
}

When a request comes in for /images/logo.png, NGINX constructs the path as:

/var/www/html + /images/logo.png = /var/www/html/images/logo.png

The full URI /images/logo.png is appended to the root path. This means your directory structure must include the /images folder inside /var/www/html.

root Directive Placement

The root directive can be placed in the http, server, or location context. It is commonly placed at the server level and inherited by all locations:

server {
    listen 80;
    root /var/www/html;

    location /images {
        # Inherits root /var/www/html
        # /images/logo.png -> /var/www/html/images/logo.png
    }

    location /css {
        # Inherits root /var/www/html
        # /css/style.css -> /var/www/html/css/style.css
    }

    location /uploads {
        # Override root for this location
        root /var/www/uploads;
        # /uploads/file.pdf -> /var/www/uploads/uploads/file.pdf
    }
}

Notice the last location block: when you override root in a location, the location path is still appended. This catches many administrators by surprise.

The alias Directive: Replacing the Location Match

The alias directive replaces the matched location portion of the URI with the specified path. This is the key difference in the NGINX alias vs root comparison.

server {
    listen 80;
    server_name example.com;

    location /images {
        alias /var/www/static/images;
    }
}

When a request comes in for /images/logo.png, NGINX constructs the path as:

/var/www/static/images + /logo.png = /var/www/static/images/logo.png

NGINX removes /images from the URI and appends only the remaining /logo.png to the alias path. The location match is replaced, not appended.

When to Use alias

Use alias when:

# Serve files from /srv/downloads when requesting /files/
location /files/ {
    alias /srv/downloads/;
}

# Serve static assets from a CDN directory
location /static/ {
    alias /var/cache/cdn/assets/;
}

# Serve user uploads from a separate partition
location /uploads/ {
    alias /mnt/storage/user-uploads/;
}

alias Restrictions

The alias directive has more restrictions than root:

  1. Cannot be used in named locations: Named locations (those starting with @) cannot use alias
  2. Cannot be used with certain rewrites: If the URI is modified by a rewrite, alias may produce unexpected results
  3. Only valid in location context: Unlike root, alias cannot be placed in http or server blocks

The Critical Trailing Slash Rule

The trailing slash is where most NGINX alias vs root confusion originates. Getting this wrong results in 404 errors that can take hours to debug.

The Rule for alias

When using alias, the trailing slashes must match between the location and the alias path:

Correct:

location /files/ {
    alias /srv/downloads/;
}

Correct:

location /files {
    alias /srv/downloads;
}

Wrong – will break:

location /files/ {
    alias /srv/downloads;  # Missing trailing slash
}

Let us see why the wrong configuration breaks. With location /files/ and alias /srv/downloads (no trailing slash):

The missing slash causes the path to be concatenated without a separator, resulting in a nonexistent path.

Why root Does Not Have This Problem

With root, the full URI is always appended, so the slash situation is consistent:

location /files {
    root /srv;
}
# /files/report.pdf -> /srv/files/report.pdf (correct)

location /files/ {
    root /srv;
}
# /files/report.pdf -> /srv/files/report.pdf (correct)

The URI always starts with a slash, so it naturally separates from the root path.

Practical Advice

To avoid trailing slash problems with alias, always follow this pattern:

location /prefix/ {
    alias /path/to/directory/;
}

Both the location and the alias end with slashes. This is the safest and most readable approach.

NGINX alias vs root with try_files

The try_files directive behaves differently with alias and root, and understanding this interaction is crucial for serving static files with fallbacks.

try_files with root

server {
    listen 80;
    root /var/www/html;

    location /assets/ {
        try_files $uri $uri/ =404;
    }
}

When requesting /assets/style.css:

  1. NGINX constructs: /var/www/html/assets/style.css
  2. If not found, tries: /var/www/html/assets/style.css/
  3. If not found, returns 404

This works as expected because root appends the full URI.

try_files with alias

server {
    listen 80;

    location /assets/ {
        alias /srv/static-files/;
        try_files $uri $uri/ =404;
    }
}

When requesting /assets/style.css:

  1. NGINX constructs: /srv/static-files/style.css
  2. If not found, tries: /srv/static-files/style.css/
  3. If not found, returns 404

The key difference is that with alias, try_files correctly uses the aliased path. The /assets/ prefix is stripped when constructing the filesystem path.

Common try_files Mistake

A frequent mistake is using alias when you should use root:

# Wrong: trying to serve /assets/* from /var/www/html/assets/
location /assets/ {
    alias /var/www/html/assets/;
    try_files $uri $uri/ =404;
}

# Better: use root when the directory structure matches
location /assets/ {
    root /var/www/html;
    try_files $uri $uri/ =404;
}

When the URL path matches the filesystem structure, prefer root for simplicity.

Using alias with Regex Locations

When using alias inside a regex location, you must use capture groups. NGINX requires this to know which part of the URI to replace.

Incorrect (will cause errors)

location ~ ^/images/ {
    alias /srv/static/images/;  # Does not work correctly with regex
}

Correct (using capture groups)

location ~ ^/users/(\d+)/avatar\.jpg$ {
    alias /srv/avatars/$1.jpg;
}

In this example:
– Request: /users/123/avatar.jpg
– Capture group $1: 123
– Resolved path: /srv/avatars/123.jpg

The regex captures the user ID, and alias uses it to construct the correct path.

Multiple Capture Groups

location ~ ^/galleries/([a-z]+)/(\d+)\.jpg$ {
    alias /srv/images/$1/photo_$2.jpg;
}

Directory Auto-Redirect Behavior

When a request matches a directory without a trailing slash, NGINX can automatically redirect to add the slash. This behavior differs slightly between root and alias.

With root

location /docs {
    root /var/www;
    index index.html;
}

Request to /docs (without trailing slash):
1. NGINX finds /var/www/docs is a directory
2. Returns 301 redirect to /docs/
3. New request to /docs/ serves /var/www/docs/index.html

With alias

location /documentation/ {
    alias /var/www/docs/;
    index index.html;
}

Request to /documentation (without trailing slash):
1. Does not match location /documentation/
2. Falls through to another location or returns 404

To handle both with and without trailing slash:

location /documentation {
    alias /var/www/docs;
    index index.html;
}

location /documentation/ {
    alias /var/www/docs/;
    index index.html;
}

Or use a rewrite:

location /documentation {
    rewrite ^/documentation$ /documentation/ permanent;
}

location /documentation/ {
    alias /var/www/docs/;
    index index.html;
}

NGINX alias vs root: Quick Reference

Aspect root alias
Path formula root + full_URI alias + (URI – location)
Valid contexts http, server, location location only
Trailing slash Not critical Must match location
Regex locations Works without changes Requires capture groups
Named locations Supported Not supported
With try_files Straightforward Works, but be careful
Default choice Yes Only when needed

When to Use root vs alias

Use root when:

Use alias when:

Testing Your Configuration

Always test your NGINX configuration before deploying:

# Verify configuration syntax
nginx -t

# Test a specific file request
curl -I http://localhost/images/logo.png

# Check the actual file path in error logs (enable debug logging)
# Add to nginx.conf: error_log /var/log/nginx/error.log debug;
tail -f /var/log/nginx/error.log | grep "http filename"

Installing NGINX

On RHEL-based systems (Rocky Linux, AlmaLinux, CentOS):

dnf install nginx
systemctl enable --now nginx

The static module that handles both root and alias is compiled in by default.

Conclusion

The difference between NGINX alias and root comes down to one key concept: root appends the entire URI to the path, while alias replaces the location match with the specified path.

Key takeaways:

Understanding how NGINX internally constructs file paths eliminates the guesswork from your configurations. The path formula tells you exactly what will happen, and matching trailing slashes prevents the most common errors.

For related NGINX configuration topics, see our guides on NGINX location priority, NGINX rewrite rules, and tuning proxy_buffer_size.

D

Danila Vershinin

Founder & Lead Engineer

NGINX configuration and optimizationLinux system administrationWeb performance engineering

10+ years NGINX experience β€’ Maintainer of GetPageSpeed RPM repository β€’ Contributor to open-source NGINX modules

Exit mobile version