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
overalias
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