How to Configure Nginx Location Block to Always Serve a Specific Static File


1 views

When setting up an Nginx server, a common requirement is to make specific paths always return particular static files while maintaining other routing rules. Here's the proper way to implement this:


server {
    listen 1337;
    charset UTF-8;

    # Root path serves single HTML file
    location = / {
        root /home/tomas/projects/streamcore/static;
        try_files /index_debug.html =404;
    }

    # Static files directory
    location /static {
        alias /home/tomas/projects/streamcore/static;
    }

    # Catch-all for 404
    location / {
        return 404;
    }
}

The 500 error occurred because alias has special behavior with exact matches (location =). When using alias in an exact match location, Nginx automatically appends the URI to the alias path - hence the "index_debug.htmlindex.html" you saw in logs.

Here are three working approaches, each with different use cases:

Option 1: Using root + try_files


location = / {
    root /path/to/static/files;
    try_files /specific_file.html =404;
}

Option 2: Using alias (correct syntax)


location /special-path {
    alias /path/to/static/files/specific_file.html;
    # Must disable automatic index processing
    index nonexistent;
}

Option 3: Using return with named location


location @serve_specific_file {
    root /path/to/files;
    try_files /target_file.html =404;
}

location / {
    try_files $uri @serve_specific_file;
}

For production environments, you might want to add caching headers and gzip compression:


location = / {
    root /var/www/static;
    try_files /app-index.html =404;
    
    # Cache control
    expires 1h;
    add_header Cache-Control "public";
    
    # Compression
    gzip on;
    gzip_types text/html;
}
  • Never end alias paths with "/" as it breaks path resolution
  • When using exact matches (=), remember it won't match "/path/" if defined as "/path"
  • Directory listings might interfere - always include autoindex off

If you encounter issues:


# Check error logs
tail -f /var/log/nginx/error.log

# Verify config syntax
sudo nginx -t

# Test actual responses
curl -v http://localhost:1337/

When configuring Nginx to serve single files for specific routes, developers often encounter unexpected behaviors. The main struggle comes from Nginx's interpretation of URI endings and its default handling of index files.

The 500 error with alias occurs because Nginx automatically appends the index file name (default: index.html) when the URI ends with a slash. That's why you see the bizarre concatenation "index_debug.htmlindex.html".

# This won't work as expected when accessing "/"
location / {
    alias /path/to/file.html;  # Will trigger index appending
}

Exact Match Location Block

The most reliable method uses an exact match location:

location = / {
    root /home/tomas/projects/streamcore/static;
    try_files /index_debug.html =404;
}

Alternative with rewrite

For more control over the URI processing:

location / {
    root /home/tomas/projects/streamcore/static;
    rewrite ^/$ /index_debug.html last;
    try_files $uri $uri/ =404;
}

Here's the full server block implementing all your requirements:

server {
    listen 1337;
    charset UTF-8;

    # Root path serves single file
    location = / {
        root /home/tomas/projects/streamcore/static;
        try_files /index_debug.html =404;
    }

    # Static files directory
    location /static {
        alias /home/tomas/projects/streamcore/static;
        try_files $uri $uri/ =404;
    }

    # Catch-all for other requests
    location / {
        return 404;
    }
}
  • Always prefer root over alias for simpler path resolution
  • The exact match (location =) prevents unwanted URI processing
  • Using try_files with single file requires the =404 fallback
  • For future WSGI integration, you'll modify the catch-all location